All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges()
@ 2019-10-28 22:51 Rob Herring
  2019-10-30 14:51   ` kbuild test robot
       [not found] ` <20191028225136.22289-1-robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
  0 siblings, 2 replies; 13+ messages in thread
From: Rob Herring @ 2019-10-28 22:51 UTC (permalink / raw)
  To: linux-pci
  Cc: Thierry Reding, Lorenzo Pieralisi, Andrew Murray, Bjorn Helgaas,
	Jonathan Hunter, linux-tegra

Convert Tegra PCI host driver to use the common
pci_parse_request_of_pci_ranges().

This allows removing the DT ranges parsing, PCI resource handling, and
private storage of resources from the driver.

Cc: Thierry Reding <thierry.reding@gmail.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Andrew Murray <andrew.murray@arm.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Jonathan Hunter <jonathanh@nvidia.com>
Cc: linux-tegra@vger.kernel.org
Signed-off-by: Rob Herring <robh@kernel.org>
---
Here's one more conversion to use pci_parse_request_of_pci_ranges. It's
dependent on my prior series, specifically this patch[1].

Compile tested only.

Rob

[1] https://patchwork.ozlabs.org/patch/1185555/

 drivers/pci/controller/pci-tegra.c | 187 +++++++----------------------
 1 file changed, 46 insertions(+), 141 deletions(-)

diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
index 673a1725ef38..83d8209a372a 100644
--- a/drivers/pci/controller/pci-tegra.c
+++ b/drivers/pci/controller/pci-tegra.c
@@ -355,16 +355,6 @@ struct tegra_pcie {
 	int irq;
 
 	struct resource cs;
-	struct resource io;
-	struct resource pio;
-	struct resource mem;
-	struct resource prefetch;
-	struct resource busn;
-
-	struct {
-		resource_size_t mem;
-		resource_size_t io;
-	} offset;
 
 	struct clk *pex_clk;
 	struct clk *afi_clk;
@@ -797,38 +787,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0bf1, tegra_pcie_relax_enable);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0e1c, tegra_pcie_relax_enable);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0e1d, tegra_pcie_relax_enable);
 
-static int tegra_pcie_request_resources(struct tegra_pcie *pcie)
-{
-	struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
-	struct list_head *windows = &host->windows;
-	struct device *dev = pcie->dev;
-	int err;
-
-	pci_add_resource_offset(windows, &pcie->pio, pcie->offset.io);
-	pci_add_resource_offset(windows, &pcie->mem, pcie->offset.mem);
-	pci_add_resource_offset(windows, &pcie->prefetch, pcie->offset.mem);
-	pci_add_resource(windows, &pcie->busn);
-
-	err = devm_request_pci_bus_resources(dev, windows);
-	if (err < 0) {
-		pci_free_resource_list(windows);
-		return err;
-	}
-
-	pci_remap_iospace(&pcie->pio, pcie->io.start);
-
-	return 0;
-}
-
-static void tegra_pcie_free_resources(struct tegra_pcie *pcie)
-{
-	struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
-	struct list_head *windows = &host->windows;
-
-	pci_unmap_iospace(&pcie->pio);
-	pci_free_resource_list(windows);
-}
-
 static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
 {
 	struct tegra_pcie *pcie = pdev->bus->sysdata;
@@ -909,36 +867,49 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
  */
 static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
 {
-	u32 fpci_bar, size, axi_address;
+	u32 size;
+	struct resource_entry *entry;
+	struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
 
 	/* Bar 0: type 1 extended configuration space */
 	size = resource_size(&pcie->cs);
 	afi_writel(pcie, pcie->cs.start, AFI_AXI_BAR0_START);
 	afi_writel(pcie, size >> 12, AFI_AXI_BAR0_SZ);
 
-	/* Bar 1: downstream IO bar */
-	fpci_bar = 0xfdfc0000;
-	size = resource_size(&pcie->io);
-	axi_address = pcie->io.start;
-	afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
-	afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
-	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
-
-	/* Bar 2: prefetchable memory BAR */
-	fpci_bar = (((pcie->prefetch.start >> 12) & 0x0fffffff) << 4) | 0x1;
-	size = resource_size(&pcie->prefetch);
-	axi_address = pcie->prefetch.start;
-	afi_writel(pcie, axi_address, AFI_AXI_BAR2_START);
-	afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ);
-	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR2);
-
-	/* Bar 3: non prefetchable memory BAR */
-	fpci_bar = (((pcie->mem.start >> 12) & 0x0fffffff) << 4) | 0x1;
-	size = resource_size(&pcie->mem);
-	axi_address = pcie->mem.start;
-	afi_writel(pcie, axi_address, AFI_AXI_BAR3_START);
-	afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ);
-	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR3);
+	resource_list_for_each_entry(entry, &bridge->windows) {
+		u32 fpci_bar, axi_address;
+		struct resource *res = entry->res;
+
+		size = resource_size(res);
+
+		switch (resource_type(res)) {
+		case IORESOURCE_IO:
+			/* Bar 1: downstream IO bar */
+			fpci_bar = 0xfdfc0000;
+			axi_address = pci_pio_to_address(res->start);
+			afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
+			afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
+			afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
+			break;
+		case IORESOURCE_MEM:
+			fpci_bar = (((res->start >> 12) & 0x0fffffff) << 4) | 0x1;
+			axi_address = res->start;
+
+			if (res->flags & IORESOURCE_PREFETCH) {
+				/* Bar 2: prefetchable memory BAR */
+				afi_writel(pcie, axi_address, AFI_AXI_BAR2_START);
+				afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ);
+				afi_writel(pcie, fpci_bar, AFI_FPCI_BAR2);
+
+			} else {
+				/* Bar 3: non prefetchable memory BAR */
+				afi_writel(pcie, axi_address, AFI_AXI_BAR3_START);
+				afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ);
+				afi_writel(pcie, fpci_bar, AFI_FPCI_BAR3);
+			}
+			break;
+		}
+	}
 
 	/* NULL out the remaining BARs as they are not used */
 	afi_writel(pcie, 0, AFI_AXI_BAR4_START);
@@ -2157,76 +2128,10 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
 	struct device *dev = pcie->dev;
 	struct device_node *np = dev->of_node, *port;
 	const struct tegra_pcie_soc *soc = pcie->soc;
-	struct of_pci_range_parser parser;
-	struct of_pci_range range;
 	u32 lanes = 0, mask = 0;
 	unsigned int lane = 0;
-	struct resource res;
 	int err;
 
-	if (of_pci_range_parser_init(&parser, np)) {
-		dev_err(dev, "missing \"ranges\" property\n");
-		return -EINVAL;
-	}
-
-	for_each_of_pci_range(&parser, &range) {
-		err = of_pci_range_to_resource(&range, np, &res);
-		if (err < 0)
-			return err;
-
-		switch (res.flags & IORESOURCE_TYPE_BITS) {
-		case IORESOURCE_IO:
-			/* Track the bus -> CPU I/O mapping offset. */
-			pcie->offset.io = res.start - range.pci_addr;
-
-			memcpy(&pcie->pio, &res, sizeof(res));
-			pcie->pio.name = np->full_name;
-
-			/*
-			 * The Tegra PCIe host bridge uses this to program the
-			 * mapping of the I/O space to the physical address,
-			 * so we override the .start and .end fields here that
-			 * of_pci_range_to_resource() converted to I/O space.
-			 * We also set the IORESOURCE_MEM type to clarify that
-			 * the resource is in the physical memory space.
-			 */
-			pcie->io.start = range.cpu_addr;
-			pcie->io.end = range.cpu_addr + range.size - 1;
-			pcie->io.flags = IORESOURCE_MEM;
-			pcie->io.name = "I/O";
-
-			memcpy(&res, &pcie->io, sizeof(res));
-			break;
-
-		case IORESOURCE_MEM:
-			/*
-			 * Track the bus -> CPU memory mapping offset. This
-			 * assumes that the prefetchable and non-prefetchable
-			 * regions will be the last of type IORESOURCE_MEM in
-			 * the ranges property.
-			 * */
-			pcie->offset.mem = res.start - range.pci_addr;
-
-			if (res.flags & IORESOURCE_PREFETCH) {
-				memcpy(&pcie->prefetch, &res, sizeof(res));
-				pcie->prefetch.name = "prefetchable";
-			} else {
-				memcpy(&pcie->mem, &res, sizeof(res));
-				pcie->mem.name = "non-prefetchable";
-			}
-			break;
-		}
-	}
-
-	err = of_pci_parse_bus_range(np, &pcie->busn);
-	if (err < 0) {
-		dev_err(dev, "failed to parse ranges property: %d\n", err);
-		pcie->busn.name = np->name;
-		pcie->busn.start = 0;
-		pcie->busn.end = 0xff;
-		pcie->busn.flags = IORESOURCE_BUS;
-	}
-
 	/* parse root ports */
 	for_each_child_of_node(np, port) {
 		struct tegra_pcie_port *rp;
@@ -2766,6 +2671,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
 	struct pci_host_bridge *host;
 	struct tegra_pcie *pcie;
 	struct pci_bus *child;
+	struct resource *bus;
 	int err;
 
 	host = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
@@ -2780,6 +2686,12 @@ static int tegra_pcie_probe(struct platform_device *pdev)
 	INIT_LIST_HEAD(&pcie->ports);
 	pcie->dev = dev;
 
+	err = pci_parse_request_of_pci_ranges(dev, &host->windows, NULL, &bus);
+	if (err) {
+		dev_err(dev, "Getting bridge resources failed\n");
+		return err;
+	}
+
 	err = tegra_pcie_parse_dt(pcie);
 	if (err < 0)
 		return err;
@@ -2803,11 +2715,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
 		goto teardown_msi;
 	}
 
-	err = tegra_pcie_request_resources(pcie);
-	if (err)
-		goto pm_runtime_put;
-
-	host->busnr = pcie->busn.start;
+	host->busnr = bus->start;
 	host->dev.parent = &pdev->dev;
 	host->ops = &tegra_pcie_ops;
 	host->map_irq = tegra_pcie_map_irq;
@@ -2816,7 +2724,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
 	err = pci_scan_root_bus_bridge(host);
 	if (err < 0) {
 		dev_err(dev, "failed to register host: %d\n", err);
-		goto free_resources;
+		goto pm_runtime_put;
 	}
 
 	pci_bus_size_bridges(host->bus);
@@ -2835,8 +2743,6 @@ static int tegra_pcie_probe(struct platform_device *pdev)
 
 	return 0;
 
-free_resources:
-	tegra_pcie_free_resources(pcie);
 pm_runtime_put:
 	pm_runtime_put_sync(pcie->dev);
 	pm_runtime_disable(pcie->dev);
@@ -2858,7 +2764,6 @@ static int tegra_pcie_remove(struct platform_device *pdev)
 
 	pci_stop_root_bus(host->bus);
 	pci_remove_root_bus(host->bus);
-	tegra_pcie_free_resources(pcie);
 	pm_runtime_put_sync(pcie->dev);
 	pm_runtime_disable(pcie->dev);
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges()
  2019-10-28 22:51 [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges() Rob Herring
@ 2019-10-30 14:51   ` kbuild test robot
       [not found] ` <20191028225136.22289-1-robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
  1 sibling, 0 replies; 13+ messages in thread
From: kbuild test robot @ 2019-10-30 14:51 UTC (permalink / raw)
  To: Rob Herring
  Cc: kbuild-all, linux-pci, Thierry Reding, Lorenzo Pieralisi,
	Andrew Murray, Bjorn Helgaas, Jonathan Hunter, linux-tegra

[-- Attachment #1: Type: text/plain, Size: 4348 bytes --]

Hi Rob,

I love your patch! Yet something to improve:

[auto build test ERROR on tegra/for-next]
[also build test ERROR on v5.4-rc5 next-20191030]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Rob-Herring/PCI-tegra-Use-pci_parse_request_of_pci_ranges/20191030-211825
base:   https://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git for-next
config: x86_64-allyesconfig (attached as .config)
compiler: gcc-7 (Debian 7.4.0-14) 7.4.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   drivers/pci/controller/pci-tegra.c: In function 'tegra_pcie_probe':
>> drivers/pci/controller/pci-tegra.c:2689:8: error: too many arguments to function 'pci_parse_request_of_pci_ranges'
     err = pci_parse_request_of_pci_ranges(dev, &host->windows, NULL, &bus);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   In file included from include/linux/of_pci.h:5:0,
                    from drivers/pci/controller/pci-tegra.c:30:
   include/linux/pci.h:2279:5: note: declared here
    int pci_parse_request_of_pci_ranges(struct device *dev,
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

vim +/pci_parse_request_of_pci_ranges +2689 drivers/pci/controller/pci-tegra.c

  2667	
  2668	static int tegra_pcie_probe(struct platform_device *pdev)
  2669	{
  2670		struct device *dev = &pdev->dev;
  2671		struct pci_host_bridge *host;
  2672		struct tegra_pcie *pcie;
  2673		struct pci_bus *child;
  2674		struct resource *bus;
  2675		int err;
  2676	
  2677		host = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
  2678		if (!host)
  2679			return -ENOMEM;
  2680	
  2681		pcie = pci_host_bridge_priv(host);
  2682		host->sysdata = pcie;
  2683		platform_set_drvdata(pdev, pcie);
  2684	
  2685		pcie->soc = of_device_get_match_data(dev);
  2686		INIT_LIST_HEAD(&pcie->ports);
  2687		pcie->dev = dev;
  2688	
> 2689		err = pci_parse_request_of_pci_ranges(dev, &host->windows, NULL, &bus);
  2690		if (err) {
  2691			dev_err(dev, "Getting bridge resources failed\n");
  2692			return err;
  2693		}
  2694	
  2695		err = tegra_pcie_parse_dt(pcie);
  2696		if (err < 0)
  2697			return err;
  2698	
  2699		err = tegra_pcie_get_resources(pcie);
  2700		if (err < 0) {
  2701			dev_err(dev, "failed to request resources: %d\n", err);
  2702			return err;
  2703		}
  2704	
  2705		err = tegra_pcie_msi_setup(pcie);
  2706		if (err < 0) {
  2707			dev_err(dev, "failed to enable MSI support: %d\n", err);
  2708			goto put_resources;
  2709		}
  2710	
  2711		pm_runtime_enable(pcie->dev);
  2712		err = pm_runtime_get_sync(pcie->dev);
  2713		if (err) {
  2714			dev_err(dev, "fail to enable pcie controller: %d\n", err);
  2715			goto teardown_msi;
  2716		}
  2717	
  2718		host->busnr = bus->start;
  2719		host->dev.parent = &pdev->dev;
  2720		host->ops = &tegra_pcie_ops;
  2721		host->map_irq = tegra_pcie_map_irq;
  2722		host->swizzle_irq = pci_common_swizzle;
  2723	
  2724		err = pci_scan_root_bus_bridge(host);
  2725		if (err < 0) {
  2726			dev_err(dev, "failed to register host: %d\n", err);
  2727			goto pm_runtime_put;
  2728		}
  2729	
  2730		pci_bus_size_bridges(host->bus);
  2731		pci_bus_assign_resources(host->bus);
  2732	
  2733		list_for_each_entry(child, &host->bus->children, node)
  2734			pcie_bus_configure_settings(child);
  2735	
  2736		pci_bus_add_devices(host->bus);
  2737	
  2738		if (IS_ENABLED(CONFIG_DEBUG_FS)) {
  2739			err = tegra_pcie_debugfs_init(pcie);
  2740			if (err < 0)
  2741				dev_err(dev, "failed to setup debugfs: %d\n", err);
  2742		}
  2743	
  2744		return 0;
  2745	
  2746	pm_runtime_put:
  2747		pm_runtime_put_sync(pcie->dev);
  2748		pm_runtime_disable(pcie->dev);
  2749	teardown_msi:
  2750		tegra_pcie_msi_teardown(pcie);
  2751	put_resources:
  2752		tegra_pcie_put_resources(pcie);
  2753		return err;
  2754	}
  2755	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 70204 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges()
@ 2019-10-30 14:51   ` kbuild test robot
  0 siblings, 0 replies; 13+ messages in thread
From: kbuild test robot @ 2019-10-30 14:51 UTC (permalink / raw)
  To: kbuild-all

[-- Attachment #1: Type: text/plain, Size: 4476 bytes --]

Hi Rob,

I love your patch! Yet something to improve:

[auto build test ERROR on tegra/for-next]
[also build test ERROR on v5.4-rc5 next-20191030]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url:    https://github.com/0day-ci/linux/commits/Rob-Herring/PCI-tegra-Use-pci_parse_request_of_pci_ranges/20191030-211825
base:   https://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux.git for-next
config: x86_64-allyesconfig (attached as .config)
compiler: gcc-7 (Debian 7.4.0-14) 7.4.0
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>

All errors (new ones prefixed by >>):

   drivers/pci/controller/pci-tegra.c: In function 'tegra_pcie_probe':
>> drivers/pci/controller/pci-tegra.c:2689:8: error: too many arguments to function 'pci_parse_request_of_pci_ranges'
     err = pci_parse_request_of_pci_ranges(dev, &host->windows, NULL, &bus);
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   In file included from include/linux/of_pci.h:5:0,
                    from drivers/pci/controller/pci-tegra.c:30:
   include/linux/pci.h:2279:5: note: declared here
    int pci_parse_request_of_pci_ranges(struct device *dev,
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

vim +/pci_parse_request_of_pci_ranges +2689 drivers/pci/controller/pci-tegra.c

  2667	
  2668	static int tegra_pcie_probe(struct platform_device *pdev)
  2669	{
  2670		struct device *dev = &pdev->dev;
  2671		struct pci_host_bridge *host;
  2672		struct tegra_pcie *pcie;
  2673		struct pci_bus *child;
  2674		struct resource *bus;
  2675		int err;
  2676	
  2677		host = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
  2678		if (!host)
  2679			return -ENOMEM;
  2680	
  2681		pcie = pci_host_bridge_priv(host);
  2682		host->sysdata = pcie;
  2683		platform_set_drvdata(pdev, pcie);
  2684	
  2685		pcie->soc = of_device_get_match_data(dev);
  2686		INIT_LIST_HEAD(&pcie->ports);
  2687		pcie->dev = dev;
  2688	
> 2689		err = pci_parse_request_of_pci_ranges(dev, &host->windows, NULL, &bus);
  2690		if (err) {
  2691			dev_err(dev, "Getting bridge resources failed\n");
  2692			return err;
  2693		}
  2694	
  2695		err = tegra_pcie_parse_dt(pcie);
  2696		if (err < 0)
  2697			return err;
  2698	
  2699		err = tegra_pcie_get_resources(pcie);
  2700		if (err < 0) {
  2701			dev_err(dev, "failed to request resources: %d\n", err);
  2702			return err;
  2703		}
  2704	
  2705		err = tegra_pcie_msi_setup(pcie);
  2706		if (err < 0) {
  2707			dev_err(dev, "failed to enable MSI support: %d\n", err);
  2708			goto put_resources;
  2709		}
  2710	
  2711		pm_runtime_enable(pcie->dev);
  2712		err = pm_runtime_get_sync(pcie->dev);
  2713		if (err) {
  2714			dev_err(dev, "fail to enable pcie controller: %d\n", err);
  2715			goto teardown_msi;
  2716		}
  2717	
  2718		host->busnr = bus->start;
  2719		host->dev.parent = &pdev->dev;
  2720		host->ops = &tegra_pcie_ops;
  2721		host->map_irq = tegra_pcie_map_irq;
  2722		host->swizzle_irq = pci_common_swizzle;
  2723	
  2724		err = pci_scan_root_bus_bridge(host);
  2725		if (err < 0) {
  2726			dev_err(dev, "failed to register host: %d\n", err);
  2727			goto pm_runtime_put;
  2728		}
  2729	
  2730		pci_bus_size_bridges(host->bus);
  2731		pci_bus_assign_resources(host->bus);
  2732	
  2733		list_for_each_entry(child, &host->bus->children, node)
  2734			pcie_bus_configure_settings(child);
  2735	
  2736		pci_bus_add_devices(host->bus);
  2737	
  2738		if (IS_ENABLED(CONFIG_DEBUG_FS)) {
  2739			err = tegra_pcie_debugfs_init(pcie);
  2740			if (err < 0)
  2741				dev_err(dev, "failed to setup debugfs: %d\n", err);
  2742		}
  2743	
  2744		return 0;
  2745	
  2746	pm_runtime_put:
  2747		pm_runtime_put_sync(pcie->dev);
  2748		pm_runtime_disable(pcie->dev);
  2749	teardown_msi:
  2750		tegra_pcie_msi_teardown(pcie);
  2751	put_resources:
  2752		tegra_pcie_put_resources(pcie);
  2753		return err;
  2754	}
  2755	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 70204 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges()
  2019-10-28 22:51 [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges() Rob Herring
@ 2020-02-21 14:20     ` Lorenzo Pieralisi
       [not found] ` <20191028225136.22289-1-robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
  1 sibling, 0 replies; 13+ messages in thread
From: Lorenzo Pieralisi @ 2020-02-21 14:20 UTC (permalink / raw)
  To: Rob Herring
  Cc: linux-pci-u79uwXL29TY76Z2rM5mHXA, Thierry Reding, Andrew Murray,
	Bjorn Helgaas, Jonathan Hunter,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA

On Mon, Oct 28, 2019 at 05:51:36PM -0500, Rob Herring wrote:
> Convert Tegra PCI host driver to use the common
> pci_parse_request_of_pci_ranges().
> 
> This allows removing the DT ranges parsing, PCI resource handling, and
> private storage of resources from the driver.
> 
> Cc: Thierry Reding <thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Cc: Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
> Cc: Andrew Murray <andrew.murray-5wv7dgnIgG8@public.gmane.org>
> Cc: Bjorn Helgaas <bhelgaas-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
> Cc: Jonathan Hunter <jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Signed-off-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> ---
> Here's one more conversion to use pci_parse_request_of_pci_ranges. It's
> dependent on my prior series, specifically this patch[1].
> 
> Compile tested only.
> 
> Rob
> 
> [1] https://patchwork.ozlabs.org/patch/1185555/
> 
>  drivers/pci/controller/pci-tegra.c | 187 +++++++----------------------
>  1 file changed, 46 insertions(+), 141 deletions(-)

Patch still applies, I need testing and ACK from Tegra maintainers
please.

Thanks,
Lorenzo

> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> index 673a1725ef38..83d8209a372a 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -355,16 +355,6 @@ struct tegra_pcie {
>  	int irq;
>  
>  	struct resource cs;
> -	struct resource io;
> -	struct resource pio;
> -	struct resource mem;
> -	struct resource prefetch;
> -	struct resource busn;
> -
> -	struct {
> -		resource_size_t mem;
> -		resource_size_t io;
> -	} offset;
>  
>  	struct clk *pex_clk;
>  	struct clk *afi_clk;
> @@ -797,38 +787,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0bf1, tegra_pcie_relax_enable);
>  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0e1c, tegra_pcie_relax_enable);
>  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0e1d, tegra_pcie_relax_enable);
>  
> -static int tegra_pcie_request_resources(struct tegra_pcie *pcie)
> -{
> -	struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
> -	struct list_head *windows = &host->windows;
> -	struct device *dev = pcie->dev;
> -	int err;
> -
> -	pci_add_resource_offset(windows, &pcie->pio, pcie->offset.io);
> -	pci_add_resource_offset(windows, &pcie->mem, pcie->offset.mem);
> -	pci_add_resource_offset(windows, &pcie->prefetch, pcie->offset.mem);
> -	pci_add_resource(windows, &pcie->busn);
> -
> -	err = devm_request_pci_bus_resources(dev, windows);
> -	if (err < 0) {
> -		pci_free_resource_list(windows);
> -		return err;
> -	}
> -
> -	pci_remap_iospace(&pcie->pio, pcie->io.start);
> -
> -	return 0;
> -}
> -
> -static void tegra_pcie_free_resources(struct tegra_pcie *pcie)
> -{
> -	struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
> -	struct list_head *windows = &host->windows;
> -
> -	pci_unmap_iospace(&pcie->pio);
> -	pci_free_resource_list(windows);
> -}
> -
>  static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
>  {
>  	struct tegra_pcie *pcie = pdev->bus->sysdata;
> @@ -909,36 +867,49 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
>   */
>  static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
>  {
> -	u32 fpci_bar, size, axi_address;
> +	u32 size;
> +	struct resource_entry *entry;
> +	struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
>  
>  	/* Bar 0: type 1 extended configuration space */
>  	size = resource_size(&pcie->cs);
>  	afi_writel(pcie, pcie->cs.start, AFI_AXI_BAR0_START);
>  	afi_writel(pcie, size >> 12, AFI_AXI_BAR0_SZ);
>  
> -	/* Bar 1: downstream IO bar */
> -	fpci_bar = 0xfdfc0000;
> -	size = resource_size(&pcie->io);
> -	axi_address = pcie->io.start;
> -	afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
> -	afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
> -	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
> -
> -	/* Bar 2: prefetchable memory BAR */
> -	fpci_bar = (((pcie->prefetch.start >> 12) & 0x0fffffff) << 4) | 0x1;
> -	size = resource_size(&pcie->prefetch);
> -	axi_address = pcie->prefetch.start;
> -	afi_writel(pcie, axi_address, AFI_AXI_BAR2_START);
> -	afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ);
> -	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR2);
> -
> -	/* Bar 3: non prefetchable memory BAR */
> -	fpci_bar = (((pcie->mem.start >> 12) & 0x0fffffff) << 4) | 0x1;
> -	size = resource_size(&pcie->mem);
> -	axi_address = pcie->mem.start;
> -	afi_writel(pcie, axi_address, AFI_AXI_BAR3_START);
> -	afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ);
> -	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR3);
> +	resource_list_for_each_entry(entry, &bridge->windows) {
> +		u32 fpci_bar, axi_address;
> +		struct resource *res = entry->res;
> +
> +		size = resource_size(res);
> +
> +		switch (resource_type(res)) {
> +		case IORESOURCE_IO:
> +			/* Bar 1: downstream IO bar */
> +			fpci_bar = 0xfdfc0000;
> +			axi_address = pci_pio_to_address(res->start);
> +			afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
> +			afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
> +			afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
> +			break;
> +		case IORESOURCE_MEM:
> +			fpci_bar = (((res->start >> 12) & 0x0fffffff) << 4) | 0x1;
> +			axi_address = res->start;
> +
> +			if (res->flags & IORESOURCE_PREFETCH) {
> +				/* Bar 2: prefetchable memory BAR */
> +				afi_writel(pcie, axi_address, AFI_AXI_BAR2_START);
> +				afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ);
> +				afi_writel(pcie, fpci_bar, AFI_FPCI_BAR2);
> +
> +			} else {
> +				/* Bar 3: non prefetchable memory BAR */
> +				afi_writel(pcie, axi_address, AFI_AXI_BAR3_START);
> +				afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ);
> +				afi_writel(pcie, fpci_bar, AFI_FPCI_BAR3);
> +			}
> +			break;
> +		}
> +	}
>  
>  	/* NULL out the remaining BARs as they are not used */
>  	afi_writel(pcie, 0, AFI_AXI_BAR4_START);
> @@ -2157,76 +2128,10 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
>  	struct device *dev = pcie->dev;
>  	struct device_node *np = dev->of_node, *port;
>  	const struct tegra_pcie_soc *soc = pcie->soc;
> -	struct of_pci_range_parser parser;
> -	struct of_pci_range range;
>  	u32 lanes = 0, mask = 0;
>  	unsigned int lane = 0;
> -	struct resource res;
>  	int err;
>  
> -	if (of_pci_range_parser_init(&parser, np)) {
> -		dev_err(dev, "missing \"ranges\" property\n");
> -		return -EINVAL;
> -	}
> -
> -	for_each_of_pci_range(&parser, &range) {
> -		err = of_pci_range_to_resource(&range, np, &res);
> -		if (err < 0)
> -			return err;
> -
> -		switch (res.flags & IORESOURCE_TYPE_BITS) {
> -		case IORESOURCE_IO:
> -			/* Track the bus -> CPU I/O mapping offset. */
> -			pcie->offset.io = res.start - range.pci_addr;
> -
> -			memcpy(&pcie->pio, &res, sizeof(res));
> -			pcie->pio.name = np->full_name;
> -
> -			/*
> -			 * The Tegra PCIe host bridge uses this to program the
> -			 * mapping of the I/O space to the physical address,
> -			 * so we override the .start and .end fields here that
> -			 * of_pci_range_to_resource() converted to I/O space.
> -			 * We also set the IORESOURCE_MEM type to clarify that
> -			 * the resource is in the physical memory space.
> -			 */
> -			pcie->io.start = range.cpu_addr;
> -			pcie->io.end = range.cpu_addr + range.size - 1;
> -			pcie->io.flags = IORESOURCE_MEM;
> -			pcie->io.name = "I/O";
> -
> -			memcpy(&res, &pcie->io, sizeof(res));
> -			break;
> -
> -		case IORESOURCE_MEM:
> -			/*
> -			 * Track the bus -> CPU memory mapping offset. This
> -			 * assumes that the prefetchable and non-prefetchable
> -			 * regions will be the last of type IORESOURCE_MEM in
> -			 * the ranges property.
> -			 * */
> -			pcie->offset.mem = res.start - range.pci_addr;
> -
> -			if (res.flags & IORESOURCE_PREFETCH) {
> -				memcpy(&pcie->prefetch, &res, sizeof(res));
> -				pcie->prefetch.name = "prefetchable";
> -			} else {
> -				memcpy(&pcie->mem, &res, sizeof(res));
> -				pcie->mem.name = "non-prefetchable";
> -			}
> -			break;
> -		}
> -	}
> -
> -	err = of_pci_parse_bus_range(np, &pcie->busn);
> -	if (err < 0) {
> -		dev_err(dev, "failed to parse ranges property: %d\n", err);
> -		pcie->busn.name = np->name;
> -		pcie->busn.start = 0;
> -		pcie->busn.end = 0xff;
> -		pcie->busn.flags = IORESOURCE_BUS;
> -	}
> -
>  	/* parse root ports */
>  	for_each_child_of_node(np, port) {
>  		struct tegra_pcie_port *rp;
> @@ -2766,6 +2671,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>  	struct pci_host_bridge *host;
>  	struct tegra_pcie *pcie;
>  	struct pci_bus *child;
> +	struct resource *bus;
>  	int err;
>  
>  	host = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
> @@ -2780,6 +2686,12 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>  	INIT_LIST_HEAD(&pcie->ports);
>  	pcie->dev = dev;
>  
> +	err = pci_parse_request_of_pci_ranges(dev, &host->windows, NULL, &bus);
> +	if (err) {
> +		dev_err(dev, "Getting bridge resources failed\n");
> +		return err;
> +	}
> +
>  	err = tegra_pcie_parse_dt(pcie);
>  	if (err < 0)
>  		return err;
> @@ -2803,11 +2715,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>  		goto teardown_msi;
>  	}
>  
> -	err = tegra_pcie_request_resources(pcie);
> -	if (err)
> -		goto pm_runtime_put;
> -
> -	host->busnr = pcie->busn.start;
> +	host->busnr = bus->start;
>  	host->dev.parent = &pdev->dev;
>  	host->ops = &tegra_pcie_ops;
>  	host->map_irq = tegra_pcie_map_irq;
> @@ -2816,7 +2724,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>  	err = pci_scan_root_bus_bridge(host);
>  	if (err < 0) {
>  		dev_err(dev, "failed to register host: %d\n", err);
> -		goto free_resources;
> +		goto pm_runtime_put;
>  	}
>  
>  	pci_bus_size_bridges(host->bus);
> @@ -2835,8 +2743,6 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>  
>  	return 0;
>  
> -free_resources:
> -	tegra_pcie_free_resources(pcie);
>  pm_runtime_put:
>  	pm_runtime_put_sync(pcie->dev);
>  	pm_runtime_disable(pcie->dev);
> @@ -2858,7 +2764,6 @@ static int tegra_pcie_remove(struct platform_device *pdev)
>  
>  	pci_stop_root_bus(host->bus);
>  	pci_remove_root_bus(host->bus);
> -	tegra_pcie_free_resources(pcie);
>  	pm_runtime_put_sync(pcie->dev);
>  	pm_runtime_disable(pcie->dev);
>  
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges()
@ 2020-02-21 14:20     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 13+ messages in thread
From: Lorenzo Pieralisi @ 2020-02-21 14:20 UTC (permalink / raw)
  To: Rob Herring
  Cc: linux-pci, Thierry Reding, Andrew Murray, Bjorn Helgaas,
	Jonathan Hunter, linux-tegra

On Mon, Oct 28, 2019 at 05:51:36PM -0500, Rob Herring wrote:
> Convert Tegra PCI host driver to use the common
> pci_parse_request_of_pci_ranges().
> 
> This allows removing the DT ranges parsing, PCI resource handling, and
> private storage of resources from the driver.
> 
> Cc: Thierry Reding <thierry.reding@gmail.com>
> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Cc: Andrew Murray <andrew.murray@arm.com>
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Jonathan Hunter <jonathanh@nvidia.com>
> Cc: linux-tegra@vger.kernel.org
> Signed-off-by: Rob Herring <robh@kernel.org>
> ---
> Here's one more conversion to use pci_parse_request_of_pci_ranges. It's
> dependent on my prior series, specifically this patch[1].
> 
> Compile tested only.
> 
> Rob
> 
> [1] https://patchwork.ozlabs.org/patch/1185555/
> 
>  drivers/pci/controller/pci-tegra.c | 187 +++++++----------------------
>  1 file changed, 46 insertions(+), 141 deletions(-)

Patch still applies, I need testing and ACK from Tegra maintainers
please.

Thanks,
Lorenzo

> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> index 673a1725ef38..83d8209a372a 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -355,16 +355,6 @@ struct tegra_pcie {
>  	int irq;
>  
>  	struct resource cs;
> -	struct resource io;
> -	struct resource pio;
> -	struct resource mem;
> -	struct resource prefetch;
> -	struct resource busn;
> -
> -	struct {
> -		resource_size_t mem;
> -		resource_size_t io;
> -	} offset;
>  
>  	struct clk *pex_clk;
>  	struct clk *afi_clk;
> @@ -797,38 +787,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0bf1, tegra_pcie_relax_enable);
>  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0e1c, tegra_pcie_relax_enable);
>  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0e1d, tegra_pcie_relax_enable);
>  
> -static int tegra_pcie_request_resources(struct tegra_pcie *pcie)
> -{
> -	struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
> -	struct list_head *windows = &host->windows;
> -	struct device *dev = pcie->dev;
> -	int err;
> -
> -	pci_add_resource_offset(windows, &pcie->pio, pcie->offset.io);
> -	pci_add_resource_offset(windows, &pcie->mem, pcie->offset.mem);
> -	pci_add_resource_offset(windows, &pcie->prefetch, pcie->offset.mem);
> -	pci_add_resource(windows, &pcie->busn);
> -
> -	err = devm_request_pci_bus_resources(dev, windows);
> -	if (err < 0) {
> -		pci_free_resource_list(windows);
> -		return err;
> -	}
> -
> -	pci_remap_iospace(&pcie->pio, pcie->io.start);
> -
> -	return 0;
> -}
> -
> -static void tegra_pcie_free_resources(struct tegra_pcie *pcie)
> -{
> -	struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
> -	struct list_head *windows = &host->windows;
> -
> -	pci_unmap_iospace(&pcie->pio);
> -	pci_free_resource_list(windows);
> -}
> -
>  static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
>  {
>  	struct tegra_pcie *pcie = pdev->bus->sysdata;
> @@ -909,36 +867,49 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
>   */
>  static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
>  {
> -	u32 fpci_bar, size, axi_address;
> +	u32 size;
> +	struct resource_entry *entry;
> +	struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
>  
>  	/* Bar 0: type 1 extended configuration space */
>  	size = resource_size(&pcie->cs);
>  	afi_writel(pcie, pcie->cs.start, AFI_AXI_BAR0_START);
>  	afi_writel(pcie, size >> 12, AFI_AXI_BAR0_SZ);
>  
> -	/* Bar 1: downstream IO bar */
> -	fpci_bar = 0xfdfc0000;
> -	size = resource_size(&pcie->io);
> -	axi_address = pcie->io.start;
> -	afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
> -	afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
> -	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
> -
> -	/* Bar 2: prefetchable memory BAR */
> -	fpci_bar = (((pcie->prefetch.start >> 12) & 0x0fffffff) << 4) | 0x1;
> -	size = resource_size(&pcie->prefetch);
> -	axi_address = pcie->prefetch.start;
> -	afi_writel(pcie, axi_address, AFI_AXI_BAR2_START);
> -	afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ);
> -	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR2);
> -
> -	/* Bar 3: non prefetchable memory BAR */
> -	fpci_bar = (((pcie->mem.start >> 12) & 0x0fffffff) << 4) | 0x1;
> -	size = resource_size(&pcie->mem);
> -	axi_address = pcie->mem.start;
> -	afi_writel(pcie, axi_address, AFI_AXI_BAR3_START);
> -	afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ);
> -	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR3);
> +	resource_list_for_each_entry(entry, &bridge->windows) {
> +		u32 fpci_bar, axi_address;
> +		struct resource *res = entry->res;
> +
> +		size = resource_size(res);
> +
> +		switch (resource_type(res)) {
> +		case IORESOURCE_IO:
> +			/* Bar 1: downstream IO bar */
> +			fpci_bar = 0xfdfc0000;
> +			axi_address = pci_pio_to_address(res->start);
> +			afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
> +			afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
> +			afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
> +			break;
> +		case IORESOURCE_MEM:
> +			fpci_bar = (((res->start >> 12) & 0x0fffffff) << 4) | 0x1;
> +			axi_address = res->start;
> +
> +			if (res->flags & IORESOURCE_PREFETCH) {
> +				/* Bar 2: prefetchable memory BAR */
> +				afi_writel(pcie, axi_address, AFI_AXI_BAR2_START);
> +				afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ);
> +				afi_writel(pcie, fpci_bar, AFI_FPCI_BAR2);
> +
> +			} else {
> +				/* Bar 3: non prefetchable memory BAR */
> +				afi_writel(pcie, axi_address, AFI_AXI_BAR3_START);
> +				afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ);
> +				afi_writel(pcie, fpci_bar, AFI_FPCI_BAR3);
> +			}
> +			break;
> +		}
> +	}
>  
>  	/* NULL out the remaining BARs as they are not used */
>  	afi_writel(pcie, 0, AFI_AXI_BAR4_START);
> @@ -2157,76 +2128,10 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
>  	struct device *dev = pcie->dev;
>  	struct device_node *np = dev->of_node, *port;
>  	const struct tegra_pcie_soc *soc = pcie->soc;
> -	struct of_pci_range_parser parser;
> -	struct of_pci_range range;
>  	u32 lanes = 0, mask = 0;
>  	unsigned int lane = 0;
> -	struct resource res;
>  	int err;
>  
> -	if (of_pci_range_parser_init(&parser, np)) {
> -		dev_err(dev, "missing \"ranges\" property\n");
> -		return -EINVAL;
> -	}
> -
> -	for_each_of_pci_range(&parser, &range) {
> -		err = of_pci_range_to_resource(&range, np, &res);
> -		if (err < 0)
> -			return err;
> -
> -		switch (res.flags & IORESOURCE_TYPE_BITS) {
> -		case IORESOURCE_IO:
> -			/* Track the bus -> CPU I/O mapping offset. */
> -			pcie->offset.io = res.start - range.pci_addr;
> -
> -			memcpy(&pcie->pio, &res, sizeof(res));
> -			pcie->pio.name = np->full_name;
> -
> -			/*
> -			 * The Tegra PCIe host bridge uses this to program the
> -			 * mapping of the I/O space to the physical address,
> -			 * so we override the .start and .end fields here that
> -			 * of_pci_range_to_resource() converted to I/O space.
> -			 * We also set the IORESOURCE_MEM type to clarify that
> -			 * the resource is in the physical memory space.
> -			 */
> -			pcie->io.start = range.cpu_addr;
> -			pcie->io.end = range.cpu_addr + range.size - 1;
> -			pcie->io.flags = IORESOURCE_MEM;
> -			pcie->io.name = "I/O";
> -
> -			memcpy(&res, &pcie->io, sizeof(res));
> -			break;
> -
> -		case IORESOURCE_MEM:
> -			/*
> -			 * Track the bus -> CPU memory mapping offset. This
> -			 * assumes that the prefetchable and non-prefetchable
> -			 * regions will be the last of type IORESOURCE_MEM in
> -			 * the ranges property.
> -			 * */
> -			pcie->offset.mem = res.start - range.pci_addr;
> -
> -			if (res.flags & IORESOURCE_PREFETCH) {
> -				memcpy(&pcie->prefetch, &res, sizeof(res));
> -				pcie->prefetch.name = "prefetchable";
> -			} else {
> -				memcpy(&pcie->mem, &res, sizeof(res));
> -				pcie->mem.name = "non-prefetchable";
> -			}
> -			break;
> -		}
> -	}
> -
> -	err = of_pci_parse_bus_range(np, &pcie->busn);
> -	if (err < 0) {
> -		dev_err(dev, "failed to parse ranges property: %d\n", err);
> -		pcie->busn.name = np->name;
> -		pcie->busn.start = 0;
> -		pcie->busn.end = 0xff;
> -		pcie->busn.flags = IORESOURCE_BUS;
> -	}
> -
>  	/* parse root ports */
>  	for_each_child_of_node(np, port) {
>  		struct tegra_pcie_port *rp;
> @@ -2766,6 +2671,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>  	struct pci_host_bridge *host;
>  	struct tegra_pcie *pcie;
>  	struct pci_bus *child;
> +	struct resource *bus;
>  	int err;
>  
>  	host = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
> @@ -2780,6 +2686,12 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>  	INIT_LIST_HEAD(&pcie->ports);
>  	pcie->dev = dev;
>  
> +	err = pci_parse_request_of_pci_ranges(dev, &host->windows, NULL, &bus);
> +	if (err) {
> +		dev_err(dev, "Getting bridge resources failed\n");
> +		return err;
> +	}
> +
>  	err = tegra_pcie_parse_dt(pcie);
>  	if (err < 0)
>  		return err;
> @@ -2803,11 +2715,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>  		goto teardown_msi;
>  	}
>  
> -	err = tegra_pcie_request_resources(pcie);
> -	if (err)
> -		goto pm_runtime_put;
> -
> -	host->busnr = pcie->busn.start;
> +	host->busnr = bus->start;
>  	host->dev.parent = &pdev->dev;
>  	host->ops = &tegra_pcie_ops;
>  	host->map_irq = tegra_pcie_map_irq;
> @@ -2816,7 +2724,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>  	err = pci_scan_root_bus_bridge(host);
>  	if (err < 0) {
>  		dev_err(dev, "failed to register host: %d\n", err);
> -		goto free_resources;
> +		goto pm_runtime_put;
>  	}
>  
>  	pci_bus_size_bridges(host->bus);
> @@ -2835,8 +2743,6 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>  
>  	return 0;
>  
> -free_resources:
> -	tegra_pcie_free_resources(pcie);
>  pm_runtime_put:
>  	pm_runtime_put_sync(pcie->dev);
>  	pm_runtime_disable(pcie->dev);
> @@ -2858,7 +2764,6 @@ static int tegra_pcie_remove(struct platform_device *pdev)
>  
>  	pci_stop_root_bus(host->bus);
>  	pci_remove_root_bus(host->bus);
> -	tegra_pcie_free_resources(pcie);
>  	pm_runtime_put_sync(pcie->dev);
>  	pm_runtime_disable(pcie->dev);
>  
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges()
  2020-02-21 14:20     ` Lorenzo Pieralisi
@ 2020-02-22 17:36         ` Vidya Sagar
  -1 siblings, 0 replies; 13+ messages in thread
From: Vidya Sagar @ 2020-02-22 17:36 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Rob Herring
  Cc: linux-pci-u79uwXL29TY76Z2rM5mHXA, Thierry Reding, Andrew Murray,
	Bjorn Helgaas, Jonathan Hunter,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA



On 2/21/2020 7:50 PM, Lorenzo Pieralisi wrote:
> External email: Use caution opening links or attachments
> 
> 
> On Mon, Oct 28, 2019 at 05:51:36PM -0500, Rob Herring wrote:
>> Convert Tegra PCI host driver to use the common
>> pci_parse_request_of_pci_ranges().
>>
>> This allows removing the DT ranges parsing, PCI resource handling, and
>> private storage of resources from the driver.
>>
>> Cc: Thierry Reding <thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
>> Cc: Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
>> Cc: Andrew Murray <andrew.murray-5wv7dgnIgG8@public.gmane.org>
>> Cc: Bjorn Helgaas <bhelgaas-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
>> Cc: Jonathan Hunter <jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
>> Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
>> Signed-off-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>> ---
>> Here's one more conversion to use pci_parse_request_of_pci_ranges. It's
>> dependent on my prior series, specifically this patch[1].
>>
>> Compile tested only.
>>
>> Rob
>>
>> [1] https://patchwork.ozlabs.org/patch/1185555/
>>
>>   drivers/pci/controller/pci-tegra.c | 187 +++++++----------------------
>>   1 file changed, 46 insertions(+), 141 deletions(-)
> 
> Patch still applies, I need testing and ACK from Tegra maintainers
> please.
I tested this patch on Jetson-TX1 with NVMe drive connected to it.
Verified basic enumeration and functionality of the drive.

Tested-by: Vidya Sagar <vidyas-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>

Thanks,
Vidya Sagar

> 
> Thanks,
> Lorenzo
> 
>> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
>> index 673a1725ef38..83d8209a372a 100644
>> --- a/drivers/pci/controller/pci-tegra.c
>> +++ b/drivers/pci/controller/pci-tegra.c
>> @@ -355,16 +355,6 @@ struct tegra_pcie {
>>        int irq;
>>
>>        struct resource cs;
>> -     struct resource io;
>> -     struct resource pio;
>> -     struct resource mem;
>> -     struct resource prefetch;
>> -     struct resource busn;
>> -
>> -     struct {
>> -             resource_size_t mem;
>> -             resource_size_t io;
>> -     } offset;
>>
>>        struct clk *pex_clk;
>>        struct clk *afi_clk;
>> @@ -797,38 +787,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0bf1, tegra_pcie_relax_enable);
>>   DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0e1c, tegra_pcie_relax_enable);
>>   DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0e1d, tegra_pcie_relax_enable);
>>
>> -static int tegra_pcie_request_resources(struct tegra_pcie *pcie)
>> -{
>> -     struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
>> -     struct list_head *windows = &host->windows;
>> -     struct device *dev = pcie->dev;
>> -     int err;
>> -
>> -     pci_add_resource_offset(windows, &pcie->pio, pcie->offset.io);
>> -     pci_add_resource_offset(windows, &pcie->mem, pcie->offset.mem);
>> -     pci_add_resource_offset(windows, &pcie->prefetch, pcie->offset.mem);
>> -     pci_add_resource(windows, &pcie->busn);
>> -
>> -     err = devm_request_pci_bus_resources(dev, windows);
>> -     if (err < 0) {
>> -             pci_free_resource_list(windows);
>> -             return err;
>> -     }
>> -
>> -     pci_remap_iospace(&pcie->pio, pcie->io.start);
>> -
>> -     return 0;
>> -}
>> -
>> -static void tegra_pcie_free_resources(struct tegra_pcie *pcie)
>> -{
>> -     struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
>> -     struct list_head *windows = &host->windows;
>> -
>> -     pci_unmap_iospace(&pcie->pio);
>> -     pci_free_resource_list(windows);
>> -}
>> -
>>   static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
>>   {
>>        struct tegra_pcie *pcie = pdev->bus->sysdata;
>> @@ -909,36 +867,49 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
>>    */
>>   static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
>>   {
>> -     u32 fpci_bar, size, axi_address;
>> +     u32 size;
>> +     struct resource_entry *entry;
>> +     struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
>>
>>        /* Bar 0: type 1 extended configuration space */
>>        size = resource_size(&pcie->cs);
>>        afi_writel(pcie, pcie->cs.start, AFI_AXI_BAR0_START);
>>        afi_writel(pcie, size >> 12, AFI_AXI_BAR0_SZ);
>>
>> -     /* Bar 1: downstream IO bar */
>> -     fpci_bar = 0xfdfc0000;
>> -     size = resource_size(&pcie->io);
>> -     axi_address = pcie->io.start;
>> -     afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
>> -     afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
>> -     afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
>> -
>> -     /* Bar 2: prefetchable memory BAR */
>> -     fpci_bar = (((pcie->prefetch.start >> 12) & 0x0fffffff) << 4) | 0x1;
>> -     size = resource_size(&pcie->prefetch);
>> -     axi_address = pcie->prefetch.start;
>> -     afi_writel(pcie, axi_address, AFI_AXI_BAR2_START);
>> -     afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ);
>> -     afi_writel(pcie, fpci_bar, AFI_FPCI_BAR2);
>> -
>> -     /* Bar 3: non prefetchable memory BAR */
>> -     fpci_bar = (((pcie->mem.start >> 12) & 0x0fffffff) << 4) | 0x1;
>> -     size = resource_size(&pcie->mem);
>> -     axi_address = pcie->mem.start;
>> -     afi_writel(pcie, axi_address, AFI_AXI_BAR3_START);
>> -     afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ);
>> -     afi_writel(pcie, fpci_bar, AFI_FPCI_BAR3);
>> +     resource_list_for_each_entry(entry, &bridge->windows) {
>> +             u32 fpci_bar, axi_address;
>> +             struct resource *res = entry->res;
>> +
>> +             size = resource_size(res);
>> +
>> +             switch (resource_type(res)) {
>> +             case IORESOURCE_IO:
>> +                     /* Bar 1: downstream IO bar */
>> +                     fpci_bar = 0xfdfc0000;
>> +                     axi_address = pci_pio_to_address(res->start);
>> +                     afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
>> +                     afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
>> +                     afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
>> +                     break;
>> +             case IORESOURCE_MEM:
>> +                     fpci_bar = (((res->start >> 12) & 0x0fffffff) << 4) | 0x1;
>> +                     axi_address = res->start;
>> +
>> +                     if (res->flags & IORESOURCE_PREFETCH) {
>> +                             /* Bar 2: prefetchable memory BAR */
>> +                             afi_writel(pcie, axi_address, AFI_AXI_BAR2_START);
>> +                             afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ);
>> +                             afi_writel(pcie, fpci_bar, AFI_FPCI_BAR2);
>> +
>> +                     } else {
>> +                             /* Bar 3: non prefetchable memory BAR */
>> +                             afi_writel(pcie, axi_address, AFI_AXI_BAR3_START);
>> +                             afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ);
>> +                             afi_writel(pcie, fpci_bar, AFI_FPCI_BAR3);
>> +                     }
>> +                     break;
>> +             }
>> +     }
>>
>>        /* NULL out the remaining BARs as they are not used */
>>        afi_writel(pcie, 0, AFI_AXI_BAR4_START);
>> @@ -2157,76 +2128,10 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
>>        struct device *dev = pcie->dev;
>>        struct device_node *np = dev->of_node, *port;
>>        const struct tegra_pcie_soc *soc = pcie->soc;
>> -     struct of_pci_range_parser parser;
>> -     struct of_pci_range range;
>>        u32 lanes = 0, mask = 0;
>>        unsigned int lane = 0;
>> -     struct resource res;
>>        int err;
>>
>> -     if (of_pci_range_parser_init(&parser, np)) {
>> -             dev_err(dev, "missing \"ranges\" property\n");
>> -             return -EINVAL;
>> -     }
>> -
>> -     for_each_of_pci_range(&parser, &range) {
>> -             err = of_pci_range_to_resource(&range, np, &res);
>> -             if (err < 0)
>> -                     return err;
>> -
>> -             switch (res.flags & IORESOURCE_TYPE_BITS) {
>> -             case IORESOURCE_IO:
>> -                     /* Track the bus -> CPU I/O mapping offset. */
>> -                     pcie->offset.io = res.start - range.pci_addr;
>> -
>> -                     memcpy(&pcie->pio, &res, sizeof(res));
>> -                     pcie->pio.name = np->full_name;
>> -
>> -                     /*
>> -                      * The Tegra PCIe host bridge uses this to program the
>> -                      * mapping of the I/O space to the physical address,
>> -                      * so we override the .start and .end fields here that
>> -                      * of_pci_range_to_resource() converted to I/O space.
>> -                      * We also set the IORESOURCE_MEM type to clarify that
>> -                      * the resource is in the physical memory space.
>> -                      */
>> -                     pcie->io.start = range.cpu_addr;
>> -                     pcie->io.end = range.cpu_addr + range.size - 1;
>> -                     pcie->io.flags = IORESOURCE_MEM;
>> -                     pcie->io.name = "I/O";
>> -
>> -                     memcpy(&res, &pcie->io, sizeof(res));
>> -                     break;
>> -
>> -             case IORESOURCE_MEM:
>> -                     /*
>> -                      * Track the bus -> CPU memory mapping offset. This
>> -                      * assumes that the prefetchable and non-prefetchable
>> -                      * regions will be the last of type IORESOURCE_MEM in
>> -                      * the ranges property.
>> -                      * */
>> -                     pcie->offset.mem = res.start - range.pci_addr;
>> -
>> -                     if (res.flags & IORESOURCE_PREFETCH) {
>> -                             memcpy(&pcie->prefetch, &res, sizeof(res));
>> -                             pcie->prefetch.name = "prefetchable";
>> -                     } else {
>> -                             memcpy(&pcie->mem, &res, sizeof(res));
>> -                             pcie->mem.name = "non-prefetchable";
>> -                     }
>> -                     break;
>> -             }
>> -     }
>> -
>> -     err = of_pci_parse_bus_range(np, &pcie->busn);
>> -     if (err < 0) {
>> -             dev_err(dev, "failed to parse ranges property: %d\n", err);
>> -             pcie->busn.name = np->name;
>> -             pcie->busn.start = 0;
>> -             pcie->busn.end = 0xff;
>> -             pcie->busn.flags = IORESOURCE_BUS;
>> -     }
>> -
>>        /* parse root ports */
>>        for_each_child_of_node(np, port) {
>>                struct tegra_pcie_port *rp;
>> @@ -2766,6 +2671,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>>        struct pci_host_bridge *host;
>>        struct tegra_pcie *pcie;
>>        struct pci_bus *child;
>> +     struct resource *bus;
>>        int err;
>>
>>        host = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
>> @@ -2780,6 +2686,12 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>>        INIT_LIST_HEAD(&pcie->ports);
>>        pcie->dev = dev;
>>
>> +     err = pci_parse_request_of_pci_ranges(dev, &host->windows, NULL, &bus);
>> +     if (err) {
>> +             dev_err(dev, "Getting bridge resources failed\n");
>> +             return err;
>> +     }
>> +
>>        err = tegra_pcie_parse_dt(pcie);
>>        if (err < 0)
>>                return err;
>> @@ -2803,11 +2715,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>>                goto teardown_msi;
>>        }
>>
>> -     err = tegra_pcie_request_resources(pcie);
>> -     if (err)
>> -             goto pm_runtime_put;
>> -
>> -     host->busnr = pcie->busn.start;
>> +     host->busnr = bus->start;
>>        host->dev.parent = &pdev->dev;
>>        host->ops = &tegra_pcie_ops;
>>        host->map_irq = tegra_pcie_map_irq;
>> @@ -2816,7 +2724,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>>        err = pci_scan_root_bus_bridge(host);
>>        if (err < 0) {
>>                dev_err(dev, "failed to register host: %d\n", err);
>> -             goto free_resources;
>> +             goto pm_runtime_put;
>>        }
>>
>>        pci_bus_size_bridges(host->bus);
>> @@ -2835,8 +2743,6 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>>
>>        return 0;
>>
>> -free_resources:
>> -     tegra_pcie_free_resources(pcie);
>>   pm_runtime_put:
>>        pm_runtime_put_sync(pcie->dev);
>>        pm_runtime_disable(pcie->dev);
>> @@ -2858,7 +2764,6 @@ static int tegra_pcie_remove(struct platform_device *pdev)
>>
>>        pci_stop_root_bus(host->bus);
>>        pci_remove_root_bus(host->bus);
>> -     tegra_pcie_free_resources(pcie);
>>        pm_runtime_put_sync(pcie->dev);
>>        pm_runtime_disable(pcie->dev);
>>
>> --
>> 2.20.1
>>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges()
@ 2020-02-22 17:36         ` Vidya Sagar
  0 siblings, 0 replies; 13+ messages in thread
From: Vidya Sagar @ 2020-02-22 17:36 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Rob Herring
  Cc: linux-pci, Thierry Reding, Andrew Murray, Bjorn Helgaas,
	Jonathan Hunter, linux-tegra



On 2/21/2020 7:50 PM, Lorenzo Pieralisi wrote:
> External email: Use caution opening links or attachments
> 
> 
> On Mon, Oct 28, 2019 at 05:51:36PM -0500, Rob Herring wrote:
>> Convert Tegra PCI host driver to use the common
>> pci_parse_request_of_pci_ranges().
>>
>> This allows removing the DT ranges parsing, PCI resource handling, and
>> private storage of resources from the driver.
>>
>> Cc: Thierry Reding <thierry.reding@gmail.com>
>> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
>> Cc: Andrew Murray <andrew.murray@arm.com>
>> Cc: Bjorn Helgaas <bhelgaas@google.com>
>> Cc: Jonathan Hunter <jonathanh@nvidia.com>
>> Cc: linux-tegra@vger.kernel.org
>> Signed-off-by: Rob Herring <robh@kernel.org>
>> ---
>> Here's one more conversion to use pci_parse_request_of_pci_ranges. It's
>> dependent on my prior series, specifically this patch[1].
>>
>> Compile tested only.
>>
>> Rob
>>
>> [1] https://patchwork.ozlabs.org/patch/1185555/
>>
>>   drivers/pci/controller/pci-tegra.c | 187 +++++++----------------------
>>   1 file changed, 46 insertions(+), 141 deletions(-)
> 
> Patch still applies, I need testing and ACK from Tegra maintainers
> please.
I tested this patch on Jetson-TX1 with NVMe drive connected to it.
Verified basic enumeration and functionality of the drive.

Tested-by: Vidya Sagar <vidyas@nvidia.com>

Thanks,
Vidya Sagar

> 
> Thanks,
> Lorenzo
> 
>> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
>> index 673a1725ef38..83d8209a372a 100644
>> --- a/drivers/pci/controller/pci-tegra.c
>> +++ b/drivers/pci/controller/pci-tegra.c
>> @@ -355,16 +355,6 @@ struct tegra_pcie {
>>        int irq;
>>
>>        struct resource cs;
>> -     struct resource io;
>> -     struct resource pio;
>> -     struct resource mem;
>> -     struct resource prefetch;
>> -     struct resource busn;
>> -
>> -     struct {
>> -             resource_size_t mem;
>> -             resource_size_t io;
>> -     } offset;
>>
>>        struct clk *pex_clk;
>>        struct clk *afi_clk;
>> @@ -797,38 +787,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0bf1, tegra_pcie_relax_enable);
>>   DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0e1c, tegra_pcie_relax_enable);
>>   DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0e1d, tegra_pcie_relax_enable);
>>
>> -static int tegra_pcie_request_resources(struct tegra_pcie *pcie)
>> -{
>> -     struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
>> -     struct list_head *windows = &host->windows;
>> -     struct device *dev = pcie->dev;
>> -     int err;
>> -
>> -     pci_add_resource_offset(windows, &pcie->pio, pcie->offset.io);
>> -     pci_add_resource_offset(windows, &pcie->mem, pcie->offset.mem);
>> -     pci_add_resource_offset(windows, &pcie->prefetch, pcie->offset.mem);
>> -     pci_add_resource(windows, &pcie->busn);
>> -
>> -     err = devm_request_pci_bus_resources(dev, windows);
>> -     if (err < 0) {
>> -             pci_free_resource_list(windows);
>> -             return err;
>> -     }
>> -
>> -     pci_remap_iospace(&pcie->pio, pcie->io.start);
>> -
>> -     return 0;
>> -}
>> -
>> -static void tegra_pcie_free_resources(struct tegra_pcie *pcie)
>> -{
>> -     struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
>> -     struct list_head *windows = &host->windows;
>> -
>> -     pci_unmap_iospace(&pcie->pio);
>> -     pci_free_resource_list(windows);
>> -}
>> -
>>   static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
>>   {
>>        struct tegra_pcie *pcie = pdev->bus->sysdata;
>> @@ -909,36 +867,49 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
>>    */
>>   static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
>>   {
>> -     u32 fpci_bar, size, axi_address;
>> +     u32 size;
>> +     struct resource_entry *entry;
>> +     struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
>>
>>        /* Bar 0: type 1 extended configuration space */
>>        size = resource_size(&pcie->cs);
>>        afi_writel(pcie, pcie->cs.start, AFI_AXI_BAR0_START);
>>        afi_writel(pcie, size >> 12, AFI_AXI_BAR0_SZ);
>>
>> -     /* Bar 1: downstream IO bar */
>> -     fpci_bar = 0xfdfc0000;
>> -     size = resource_size(&pcie->io);
>> -     axi_address = pcie->io.start;
>> -     afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
>> -     afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
>> -     afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
>> -
>> -     /* Bar 2: prefetchable memory BAR */
>> -     fpci_bar = (((pcie->prefetch.start >> 12) & 0x0fffffff) << 4) | 0x1;
>> -     size = resource_size(&pcie->prefetch);
>> -     axi_address = pcie->prefetch.start;
>> -     afi_writel(pcie, axi_address, AFI_AXI_BAR2_START);
>> -     afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ);
>> -     afi_writel(pcie, fpci_bar, AFI_FPCI_BAR2);
>> -
>> -     /* Bar 3: non prefetchable memory BAR */
>> -     fpci_bar = (((pcie->mem.start >> 12) & 0x0fffffff) << 4) | 0x1;
>> -     size = resource_size(&pcie->mem);
>> -     axi_address = pcie->mem.start;
>> -     afi_writel(pcie, axi_address, AFI_AXI_BAR3_START);
>> -     afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ);
>> -     afi_writel(pcie, fpci_bar, AFI_FPCI_BAR3);
>> +     resource_list_for_each_entry(entry, &bridge->windows) {
>> +             u32 fpci_bar, axi_address;
>> +             struct resource *res = entry->res;
>> +
>> +             size = resource_size(res);
>> +
>> +             switch (resource_type(res)) {
>> +             case IORESOURCE_IO:
>> +                     /* Bar 1: downstream IO bar */
>> +                     fpci_bar = 0xfdfc0000;
>> +                     axi_address = pci_pio_to_address(res->start);
>> +                     afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
>> +                     afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
>> +                     afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
>> +                     break;
>> +             case IORESOURCE_MEM:
>> +                     fpci_bar = (((res->start >> 12) & 0x0fffffff) << 4) | 0x1;
>> +                     axi_address = res->start;
>> +
>> +                     if (res->flags & IORESOURCE_PREFETCH) {
>> +                             /* Bar 2: prefetchable memory BAR */
>> +                             afi_writel(pcie, axi_address, AFI_AXI_BAR2_START);
>> +                             afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ);
>> +                             afi_writel(pcie, fpci_bar, AFI_FPCI_BAR2);
>> +
>> +                     } else {
>> +                             /* Bar 3: non prefetchable memory BAR */
>> +                             afi_writel(pcie, axi_address, AFI_AXI_BAR3_START);
>> +                             afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ);
>> +                             afi_writel(pcie, fpci_bar, AFI_FPCI_BAR3);
>> +                     }
>> +                     break;
>> +             }
>> +     }
>>
>>        /* NULL out the remaining BARs as they are not used */
>>        afi_writel(pcie, 0, AFI_AXI_BAR4_START);
>> @@ -2157,76 +2128,10 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
>>        struct device *dev = pcie->dev;
>>        struct device_node *np = dev->of_node, *port;
>>        const struct tegra_pcie_soc *soc = pcie->soc;
>> -     struct of_pci_range_parser parser;
>> -     struct of_pci_range range;
>>        u32 lanes = 0, mask = 0;
>>        unsigned int lane = 0;
>> -     struct resource res;
>>        int err;
>>
>> -     if (of_pci_range_parser_init(&parser, np)) {
>> -             dev_err(dev, "missing \"ranges\" property\n");
>> -             return -EINVAL;
>> -     }
>> -
>> -     for_each_of_pci_range(&parser, &range) {
>> -             err = of_pci_range_to_resource(&range, np, &res);
>> -             if (err < 0)
>> -                     return err;
>> -
>> -             switch (res.flags & IORESOURCE_TYPE_BITS) {
>> -             case IORESOURCE_IO:
>> -                     /* Track the bus -> CPU I/O mapping offset. */
>> -                     pcie->offset.io = res.start - range.pci_addr;
>> -
>> -                     memcpy(&pcie->pio, &res, sizeof(res));
>> -                     pcie->pio.name = np->full_name;
>> -
>> -                     /*
>> -                      * The Tegra PCIe host bridge uses this to program the
>> -                      * mapping of the I/O space to the physical address,
>> -                      * so we override the .start and .end fields here that
>> -                      * of_pci_range_to_resource() converted to I/O space.
>> -                      * We also set the IORESOURCE_MEM type to clarify that
>> -                      * the resource is in the physical memory space.
>> -                      */
>> -                     pcie->io.start = range.cpu_addr;
>> -                     pcie->io.end = range.cpu_addr + range.size - 1;
>> -                     pcie->io.flags = IORESOURCE_MEM;
>> -                     pcie->io.name = "I/O";
>> -
>> -                     memcpy(&res, &pcie->io, sizeof(res));
>> -                     break;
>> -
>> -             case IORESOURCE_MEM:
>> -                     /*
>> -                      * Track the bus -> CPU memory mapping offset. This
>> -                      * assumes that the prefetchable and non-prefetchable
>> -                      * regions will be the last of type IORESOURCE_MEM in
>> -                      * the ranges property.
>> -                      * */
>> -                     pcie->offset.mem = res.start - range.pci_addr;
>> -
>> -                     if (res.flags & IORESOURCE_PREFETCH) {
>> -                             memcpy(&pcie->prefetch, &res, sizeof(res));
>> -                             pcie->prefetch.name = "prefetchable";
>> -                     } else {
>> -                             memcpy(&pcie->mem, &res, sizeof(res));
>> -                             pcie->mem.name = "non-prefetchable";
>> -                     }
>> -                     break;
>> -             }
>> -     }
>> -
>> -     err = of_pci_parse_bus_range(np, &pcie->busn);
>> -     if (err < 0) {
>> -             dev_err(dev, "failed to parse ranges property: %d\n", err);
>> -             pcie->busn.name = np->name;
>> -             pcie->busn.start = 0;
>> -             pcie->busn.end = 0xff;
>> -             pcie->busn.flags = IORESOURCE_BUS;
>> -     }
>> -
>>        /* parse root ports */
>>        for_each_child_of_node(np, port) {
>>                struct tegra_pcie_port *rp;
>> @@ -2766,6 +2671,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>>        struct pci_host_bridge *host;
>>        struct tegra_pcie *pcie;
>>        struct pci_bus *child;
>> +     struct resource *bus;
>>        int err;
>>
>>        host = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
>> @@ -2780,6 +2686,12 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>>        INIT_LIST_HEAD(&pcie->ports);
>>        pcie->dev = dev;
>>
>> +     err = pci_parse_request_of_pci_ranges(dev, &host->windows, NULL, &bus);
>> +     if (err) {
>> +             dev_err(dev, "Getting bridge resources failed\n");
>> +             return err;
>> +     }
>> +
>>        err = tegra_pcie_parse_dt(pcie);
>>        if (err < 0)
>>                return err;
>> @@ -2803,11 +2715,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>>                goto teardown_msi;
>>        }
>>
>> -     err = tegra_pcie_request_resources(pcie);
>> -     if (err)
>> -             goto pm_runtime_put;
>> -
>> -     host->busnr = pcie->busn.start;
>> +     host->busnr = bus->start;
>>        host->dev.parent = &pdev->dev;
>>        host->ops = &tegra_pcie_ops;
>>        host->map_irq = tegra_pcie_map_irq;
>> @@ -2816,7 +2724,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>>        err = pci_scan_root_bus_bridge(host);
>>        if (err < 0) {
>>                dev_err(dev, "failed to register host: %d\n", err);
>> -             goto free_resources;
>> +             goto pm_runtime_put;
>>        }
>>
>>        pci_bus_size_bridges(host->bus);
>> @@ -2835,8 +2743,6 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>>
>>        return 0;
>>
>> -free_resources:
>> -     tegra_pcie_free_resources(pcie);
>>   pm_runtime_put:
>>        pm_runtime_put_sync(pcie->dev);
>>        pm_runtime_disable(pcie->dev);
>> @@ -2858,7 +2764,6 @@ static int tegra_pcie_remove(struct platform_device *pdev)
>>
>>        pci_stop_root_bus(host->bus);
>>        pci_remove_root_bus(host->bus);
>> -     tegra_pcie_free_resources(pcie);
>>        pm_runtime_put_sync(pcie->dev);
>>        pm_runtime_disable(pcie->dev);
>>
>> --
>> 2.20.1
>>

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges()
  2020-02-22 17:36         ` Vidya Sagar
@ 2020-02-24 11:37             ` Lorenzo Pieralisi
  -1 siblings, 0 replies; 13+ messages in thread
From: Lorenzo Pieralisi @ 2020-02-24 11:37 UTC (permalink / raw)
  To: Vidya Sagar
  Cc: Rob Herring, linux-pci-u79uwXL29TY76Z2rM5mHXA, Thierry Reding,
	Andrew Murray, Bjorn Helgaas, Jonathan Hunter,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA

On Sat, Feb 22, 2020 at 11:06:18PM +0530, Vidya Sagar wrote:
> 
> 
> On 2/21/2020 7:50 PM, Lorenzo Pieralisi wrote:
> > External email: Use caution opening links or attachments
> > 
> > 
> > On Mon, Oct 28, 2019 at 05:51:36PM -0500, Rob Herring wrote:
> > > Convert Tegra PCI host driver to use the common
> > > pci_parse_request_of_pci_ranges().
> > > 
> > > This allows removing the DT ranges parsing, PCI resource handling, and
> > > private storage of resources from the driver.
> > > 
> > > Cc: Thierry Reding <thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> > > Cc: Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
> > > Cc: Andrew Murray <andrew.murray-5wv7dgnIgG8@public.gmane.org>
> > > Cc: Bjorn Helgaas <bhelgaas-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
> > > Cc: Jonathan Hunter <jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> > > Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> > > Signed-off-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> > > ---
> > > Here's one more conversion to use pci_parse_request_of_pci_ranges. It's
> > > dependent on my prior series, specifically this patch[1].
> > > 
> > > Compile tested only.
> > > 
> > > Rob
> > > 
> > > [1] https://patchwork.ozlabs.org/patch/1185555/
> > > 
> > >   drivers/pci/controller/pci-tegra.c | 187 +++++++----------------------
> > >   1 file changed, 46 insertions(+), 141 deletions(-)
> > 
> > Patch still applies, I need testing and ACK from Tegra maintainers
> > please.
> I tested this patch on Jetson-TX1 with NVMe drive connected to it.
> Verified basic enumeration and functionality of the drive.
> 
> Tested-by: Vidya Sagar <vidyas-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>

Thanks a lot, I need Thierry's ACK to merge it, thanks.

Lorenzo

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges()
@ 2020-02-24 11:37             ` Lorenzo Pieralisi
  0 siblings, 0 replies; 13+ messages in thread
From: Lorenzo Pieralisi @ 2020-02-24 11:37 UTC (permalink / raw)
  To: Vidya Sagar
  Cc: Rob Herring, linux-pci, Thierry Reding, Andrew Murray,
	Bjorn Helgaas, Jonathan Hunter, linux-tegra

On Sat, Feb 22, 2020 at 11:06:18PM +0530, Vidya Sagar wrote:
> 
> 
> On 2/21/2020 7:50 PM, Lorenzo Pieralisi wrote:
> > External email: Use caution opening links or attachments
> > 
> > 
> > On Mon, Oct 28, 2019 at 05:51:36PM -0500, Rob Herring wrote:
> > > Convert Tegra PCI host driver to use the common
> > > pci_parse_request_of_pci_ranges().
> > > 
> > > This allows removing the DT ranges parsing, PCI resource handling, and
> > > private storage of resources from the driver.
> > > 
> > > Cc: Thierry Reding <thierry.reding@gmail.com>
> > > Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> > > Cc: Andrew Murray <andrew.murray@arm.com>
> > > Cc: Bjorn Helgaas <bhelgaas@google.com>
> > > Cc: Jonathan Hunter <jonathanh@nvidia.com>
> > > Cc: linux-tegra@vger.kernel.org
> > > Signed-off-by: Rob Herring <robh@kernel.org>
> > > ---
> > > Here's one more conversion to use pci_parse_request_of_pci_ranges. It's
> > > dependent on my prior series, specifically this patch[1].
> > > 
> > > Compile tested only.
> > > 
> > > Rob
> > > 
> > > [1] https://patchwork.ozlabs.org/patch/1185555/
> > > 
> > >   drivers/pci/controller/pci-tegra.c | 187 +++++++----------------------
> > >   1 file changed, 46 insertions(+), 141 deletions(-)
> > 
> > Patch still applies, I need testing and ACK from Tegra maintainers
> > please.
> I tested this patch on Jetson-TX1 with NVMe drive connected to it.
> Verified basic enumeration and functionality of the drive.
> 
> Tested-by: Vidya Sagar <vidyas@nvidia.com>

Thanks a lot, I need Thierry's ACK to merge it, thanks.

Lorenzo

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges()
  2019-10-28 22:51 [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges() Rob Herring
@ 2020-02-24 13:17     ` Thierry Reding
       [not found] ` <20191028225136.22289-1-robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
  1 sibling, 0 replies; 13+ messages in thread
From: Thierry Reding @ 2020-02-24 13:17 UTC (permalink / raw)
  To: Rob Herring
  Cc: linux-pci-u79uwXL29TY76Z2rM5mHXA, Lorenzo Pieralisi,
	Andrew Murray, Bjorn Helgaas, Jonathan Hunter,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: text/plain, Size: 1233 bytes --]

On Mon, Oct 28, 2019 at 05:51:36PM -0500, Rob Herring wrote:
> Convert Tegra PCI host driver to use the common
> pci_parse_request_of_pci_ranges().
> 
> This allows removing the DT ranges parsing, PCI resource handling, and
> private storage of resources from the driver.
> 
> Cc: Thierry Reding <thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Cc: Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
> Cc: Andrew Murray <andrew.murray-5wv7dgnIgG8@public.gmane.org>
> Cc: Bjorn Helgaas <bhelgaas-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
> Cc: Jonathan Hunter <jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Signed-off-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> ---
> Here's one more conversion to use pci_parse_request_of_pci_ranges. It's
> dependent on my prior series, specifically this patch[1].
> 
> Compile tested only.
> 
> Rob
> 
> [1] https://patchwork.ozlabs.org/patch/1185555/
> 
>  drivers/pci/controller/pci-tegra.c | 187 +++++++----------------------
>  1 file changed, 46 insertions(+), 141 deletions(-)

Acked-by: Thierry Reding <treding-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges()
@ 2020-02-24 13:17     ` Thierry Reding
  0 siblings, 0 replies; 13+ messages in thread
From: Thierry Reding @ 2020-02-24 13:17 UTC (permalink / raw)
  To: Rob Herring
  Cc: linux-pci, Lorenzo Pieralisi, Andrew Murray, Bjorn Helgaas,
	Jonathan Hunter, linux-tegra

[-- Attachment #1: Type: text/plain, Size: 1021 bytes --]

On Mon, Oct 28, 2019 at 05:51:36PM -0500, Rob Herring wrote:
> Convert Tegra PCI host driver to use the common
> pci_parse_request_of_pci_ranges().
> 
> This allows removing the DT ranges parsing, PCI resource handling, and
> private storage of resources from the driver.
> 
> Cc: Thierry Reding <thierry.reding@gmail.com>
> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Cc: Andrew Murray <andrew.murray@arm.com>
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Jonathan Hunter <jonathanh@nvidia.com>
> Cc: linux-tegra@vger.kernel.org
> Signed-off-by: Rob Herring <robh@kernel.org>
> ---
> Here's one more conversion to use pci_parse_request_of_pci_ranges. It's
> dependent on my prior series, specifically this patch[1].
> 
> Compile tested only.
> 
> Rob
> 
> [1] https://patchwork.ozlabs.org/patch/1185555/
> 
>  drivers/pci/controller/pci-tegra.c | 187 +++++++----------------------
>  1 file changed, 46 insertions(+), 141 deletions(-)

Acked-by: Thierry Reding <treding@nvidia.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges()
  2019-10-28 22:51 [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges() Rob Herring
@ 2020-02-24 13:55     ` Lorenzo Pieralisi
       [not found] ` <20191028225136.22289-1-robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
  1 sibling, 0 replies; 13+ messages in thread
From: Lorenzo Pieralisi @ 2020-02-24 13:55 UTC (permalink / raw)
  To: Rob Herring
  Cc: linux-pci-u79uwXL29TY76Z2rM5mHXA, Thierry Reding, Andrew Murray,
	Bjorn Helgaas, Jonathan Hunter,
	linux-tegra-u79uwXL29TY76Z2rM5mHXA

On Mon, Oct 28, 2019 at 05:51:36PM -0500, Rob Herring wrote:
> Convert Tegra PCI host driver to use the common
> pci_parse_request_of_pci_ranges().
> 
> This allows removing the DT ranges parsing, PCI resource handling, and
> private storage of resources from the driver.
> 
> Cc: Thierry Reding <thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> Cc: Lorenzo Pieralisi <lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org>
> Cc: Andrew Murray <andrew.murray-5wv7dgnIgG8@public.gmane.org>
> Cc: Bjorn Helgaas <bhelgaas-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
> Cc: Jonathan Hunter <jonathanh-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> Cc: linux-tegra-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> Signed-off-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> ---
> Here's one more conversion to use pci_parse_request_of_pci_ranges. It's
> dependent on my prior series, specifically this patch[1].
> 
> Compile tested only.
> 
> Rob
> 
> [1] https://patchwork.ozlabs.org/patch/1185555/
> 
>  drivers/pci/controller/pci-tegra.c | 187 +++++++----------------------
>  1 file changed, 46 insertions(+), 141 deletions(-)

Applied to pci/tegra for v5.7, thanks.

Lorenzo

> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> index 673a1725ef38..83d8209a372a 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -355,16 +355,6 @@ struct tegra_pcie {
>  	int irq;
>  
>  	struct resource cs;
> -	struct resource io;
> -	struct resource pio;
> -	struct resource mem;
> -	struct resource prefetch;
> -	struct resource busn;
> -
> -	struct {
> -		resource_size_t mem;
> -		resource_size_t io;
> -	} offset;
>  
>  	struct clk *pex_clk;
>  	struct clk *afi_clk;
> @@ -797,38 +787,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0bf1, tegra_pcie_relax_enable);
>  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0e1c, tegra_pcie_relax_enable);
>  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0e1d, tegra_pcie_relax_enable);
>  
> -static int tegra_pcie_request_resources(struct tegra_pcie *pcie)
> -{
> -	struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
> -	struct list_head *windows = &host->windows;
> -	struct device *dev = pcie->dev;
> -	int err;
> -
> -	pci_add_resource_offset(windows, &pcie->pio, pcie->offset.io);
> -	pci_add_resource_offset(windows, &pcie->mem, pcie->offset.mem);
> -	pci_add_resource_offset(windows, &pcie->prefetch, pcie->offset.mem);
> -	pci_add_resource(windows, &pcie->busn);
> -
> -	err = devm_request_pci_bus_resources(dev, windows);
> -	if (err < 0) {
> -		pci_free_resource_list(windows);
> -		return err;
> -	}
> -
> -	pci_remap_iospace(&pcie->pio, pcie->io.start);
> -
> -	return 0;
> -}
> -
> -static void tegra_pcie_free_resources(struct tegra_pcie *pcie)
> -{
> -	struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
> -	struct list_head *windows = &host->windows;
> -
> -	pci_unmap_iospace(&pcie->pio);
> -	pci_free_resource_list(windows);
> -}
> -
>  static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
>  {
>  	struct tegra_pcie *pcie = pdev->bus->sysdata;
> @@ -909,36 +867,49 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
>   */
>  static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
>  {
> -	u32 fpci_bar, size, axi_address;
> +	u32 size;
> +	struct resource_entry *entry;
> +	struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
>  
>  	/* Bar 0: type 1 extended configuration space */
>  	size = resource_size(&pcie->cs);
>  	afi_writel(pcie, pcie->cs.start, AFI_AXI_BAR0_START);
>  	afi_writel(pcie, size >> 12, AFI_AXI_BAR0_SZ);
>  
> -	/* Bar 1: downstream IO bar */
> -	fpci_bar = 0xfdfc0000;
> -	size = resource_size(&pcie->io);
> -	axi_address = pcie->io.start;
> -	afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
> -	afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
> -	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
> -
> -	/* Bar 2: prefetchable memory BAR */
> -	fpci_bar = (((pcie->prefetch.start >> 12) & 0x0fffffff) << 4) | 0x1;
> -	size = resource_size(&pcie->prefetch);
> -	axi_address = pcie->prefetch.start;
> -	afi_writel(pcie, axi_address, AFI_AXI_BAR2_START);
> -	afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ);
> -	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR2);
> -
> -	/* Bar 3: non prefetchable memory BAR */
> -	fpci_bar = (((pcie->mem.start >> 12) & 0x0fffffff) << 4) | 0x1;
> -	size = resource_size(&pcie->mem);
> -	axi_address = pcie->mem.start;
> -	afi_writel(pcie, axi_address, AFI_AXI_BAR3_START);
> -	afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ);
> -	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR3);
> +	resource_list_for_each_entry(entry, &bridge->windows) {
> +		u32 fpci_bar, axi_address;
> +		struct resource *res = entry->res;
> +
> +		size = resource_size(res);
> +
> +		switch (resource_type(res)) {
> +		case IORESOURCE_IO:
> +			/* Bar 1: downstream IO bar */
> +			fpci_bar = 0xfdfc0000;
> +			axi_address = pci_pio_to_address(res->start);
> +			afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
> +			afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
> +			afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
> +			break;
> +		case IORESOURCE_MEM:
> +			fpci_bar = (((res->start >> 12) & 0x0fffffff) << 4) | 0x1;
> +			axi_address = res->start;
> +
> +			if (res->flags & IORESOURCE_PREFETCH) {
> +				/* Bar 2: prefetchable memory BAR */
> +				afi_writel(pcie, axi_address, AFI_AXI_BAR2_START);
> +				afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ);
> +				afi_writel(pcie, fpci_bar, AFI_FPCI_BAR2);
> +
> +			} else {
> +				/* Bar 3: non prefetchable memory BAR */
> +				afi_writel(pcie, axi_address, AFI_AXI_BAR3_START);
> +				afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ);
> +				afi_writel(pcie, fpci_bar, AFI_FPCI_BAR3);
> +			}
> +			break;
> +		}
> +	}
>  
>  	/* NULL out the remaining BARs as they are not used */
>  	afi_writel(pcie, 0, AFI_AXI_BAR4_START);
> @@ -2157,76 +2128,10 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
>  	struct device *dev = pcie->dev;
>  	struct device_node *np = dev->of_node, *port;
>  	const struct tegra_pcie_soc *soc = pcie->soc;
> -	struct of_pci_range_parser parser;
> -	struct of_pci_range range;
>  	u32 lanes = 0, mask = 0;
>  	unsigned int lane = 0;
> -	struct resource res;
>  	int err;
>  
> -	if (of_pci_range_parser_init(&parser, np)) {
> -		dev_err(dev, "missing \"ranges\" property\n");
> -		return -EINVAL;
> -	}
> -
> -	for_each_of_pci_range(&parser, &range) {
> -		err = of_pci_range_to_resource(&range, np, &res);
> -		if (err < 0)
> -			return err;
> -
> -		switch (res.flags & IORESOURCE_TYPE_BITS) {
> -		case IORESOURCE_IO:
> -			/* Track the bus -> CPU I/O mapping offset. */
> -			pcie->offset.io = res.start - range.pci_addr;
> -
> -			memcpy(&pcie->pio, &res, sizeof(res));
> -			pcie->pio.name = np->full_name;
> -
> -			/*
> -			 * The Tegra PCIe host bridge uses this to program the
> -			 * mapping of the I/O space to the physical address,
> -			 * so we override the .start and .end fields here that
> -			 * of_pci_range_to_resource() converted to I/O space.
> -			 * We also set the IORESOURCE_MEM type to clarify that
> -			 * the resource is in the physical memory space.
> -			 */
> -			pcie->io.start = range.cpu_addr;
> -			pcie->io.end = range.cpu_addr + range.size - 1;
> -			pcie->io.flags = IORESOURCE_MEM;
> -			pcie->io.name = "I/O";
> -
> -			memcpy(&res, &pcie->io, sizeof(res));
> -			break;
> -
> -		case IORESOURCE_MEM:
> -			/*
> -			 * Track the bus -> CPU memory mapping offset. This
> -			 * assumes that the prefetchable and non-prefetchable
> -			 * regions will be the last of type IORESOURCE_MEM in
> -			 * the ranges property.
> -			 * */
> -			pcie->offset.mem = res.start - range.pci_addr;
> -
> -			if (res.flags & IORESOURCE_PREFETCH) {
> -				memcpy(&pcie->prefetch, &res, sizeof(res));
> -				pcie->prefetch.name = "prefetchable";
> -			} else {
> -				memcpy(&pcie->mem, &res, sizeof(res));
> -				pcie->mem.name = "non-prefetchable";
> -			}
> -			break;
> -		}
> -	}
> -
> -	err = of_pci_parse_bus_range(np, &pcie->busn);
> -	if (err < 0) {
> -		dev_err(dev, "failed to parse ranges property: %d\n", err);
> -		pcie->busn.name = np->name;
> -		pcie->busn.start = 0;
> -		pcie->busn.end = 0xff;
> -		pcie->busn.flags = IORESOURCE_BUS;
> -	}
> -
>  	/* parse root ports */
>  	for_each_child_of_node(np, port) {
>  		struct tegra_pcie_port *rp;
> @@ -2766,6 +2671,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>  	struct pci_host_bridge *host;
>  	struct tegra_pcie *pcie;
>  	struct pci_bus *child;
> +	struct resource *bus;
>  	int err;
>  
>  	host = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
> @@ -2780,6 +2686,12 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>  	INIT_LIST_HEAD(&pcie->ports);
>  	pcie->dev = dev;
>  
> +	err = pci_parse_request_of_pci_ranges(dev, &host->windows, NULL, &bus);
> +	if (err) {
> +		dev_err(dev, "Getting bridge resources failed\n");
> +		return err;
> +	}
> +
>  	err = tegra_pcie_parse_dt(pcie);
>  	if (err < 0)
>  		return err;
> @@ -2803,11 +2715,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>  		goto teardown_msi;
>  	}
>  
> -	err = tegra_pcie_request_resources(pcie);
> -	if (err)
> -		goto pm_runtime_put;
> -
> -	host->busnr = pcie->busn.start;
> +	host->busnr = bus->start;
>  	host->dev.parent = &pdev->dev;
>  	host->ops = &tegra_pcie_ops;
>  	host->map_irq = tegra_pcie_map_irq;
> @@ -2816,7 +2724,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>  	err = pci_scan_root_bus_bridge(host);
>  	if (err < 0) {
>  		dev_err(dev, "failed to register host: %d\n", err);
> -		goto free_resources;
> +		goto pm_runtime_put;
>  	}
>  
>  	pci_bus_size_bridges(host->bus);
> @@ -2835,8 +2743,6 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>  
>  	return 0;
>  
> -free_resources:
> -	tegra_pcie_free_resources(pcie);
>  pm_runtime_put:
>  	pm_runtime_put_sync(pcie->dev);
>  	pm_runtime_disable(pcie->dev);
> @@ -2858,7 +2764,6 @@ static int tegra_pcie_remove(struct platform_device *pdev)
>  
>  	pci_stop_root_bus(host->bus);
>  	pci_remove_root_bus(host->bus);
> -	tegra_pcie_free_resources(pcie);
>  	pm_runtime_put_sync(pcie->dev);
>  	pm_runtime_disable(pcie->dev);
>  
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges()
@ 2020-02-24 13:55     ` Lorenzo Pieralisi
  0 siblings, 0 replies; 13+ messages in thread
From: Lorenzo Pieralisi @ 2020-02-24 13:55 UTC (permalink / raw)
  To: Rob Herring
  Cc: linux-pci, Thierry Reding, Andrew Murray, Bjorn Helgaas,
	Jonathan Hunter, linux-tegra

On Mon, Oct 28, 2019 at 05:51:36PM -0500, Rob Herring wrote:
> Convert Tegra PCI host driver to use the common
> pci_parse_request_of_pci_ranges().
> 
> This allows removing the DT ranges parsing, PCI resource handling, and
> private storage of resources from the driver.
> 
> Cc: Thierry Reding <thierry.reding@gmail.com>
> Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
> Cc: Andrew Murray <andrew.murray@arm.com>
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Jonathan Hunter <jonathanh@nvidia.com>
> Cc: linux-tegra@vger.kernel.org
> Signed-off-by: Rob Herring <robh@kernel.org>
> ---
> Here's one more conversion to use pci_parse_request_of_pci_ranges. It's
> dependent on my prior series, specifically this patch[1].
> 
> Compile tested only.
> 
> Rob
> 
> [1] https://patchwork.ozlabs.org/patch/1185555/
> 
>  drivers/pci/controller/pci-tegra.c | 187 +++++++----------------------
>  1 file changed, 46 insertions(+), 141 deletions(-)

Applied to pci/tegra for v5.7, thanks.

Lorenzo

> diff --git a/drivers/pci/controller/pci-tegra.c b/drivers/pci/controller/pci-tegra.c
> index 673a1725ef38..83d8209a372a 100644
> --- a/drivers/pci/controller/pci-tegra.c
> +++ b/drivers/pci/controller/pci-tegra.c
> @@ -355,16 +355,6 @@ struct tegra_pcie {
>  	int irq;
>  
>  	struct resource cs;
> -	struct resource io;
> -	struct resource pio;
> -	struct resource mem;
> -	struct resource prefetch;
> -	struct resource busn;
> -
> -	struct {
> -		resource_size_t mem;
> -		resource_size_t io;
> -	} offset;
>  
>  	struct clk *pex_clk;
>  	struct clk *afi_clk;
> @@ -797,38 +787,6 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0bf1, tegra_pcie_relax_enable);
>  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0e1c, tegra_pcie_relax_enable);
>  DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, 0x0e1d, tegra_pcie_relax_enable);
>  
> -static int tegra_pcie_request_resources(struct tegra_pcie *pcie)
> -{
> -	struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
> -	struct list_head *windows = &host->windows;
> -	struct device *dev = pcie->dev;
> -	int err;
> -
> -	pci_add_resource_offset(windows, &pcie->pio, pcie->offset.io);
> -	pci_add_resource_offset(windows, &pcie->mem, pcie->offset.mem);
> -	pci_add_resource_offset(windows, &pcie->prefetch, pcie->offset.mem);
> -	pci_add_resource(windows, &pcie->busn);
> -
> -	err = devm_request_pci_bus_resources(dev, windows);
> -	if (err < 0) {
> -		pci_free_resource_list(windows);
> -		return err;
> -	}
> -
> -	pci_remap_iospace(&pcie->pio, pcie->io.start);
> -
> -	return 0;
> -}
> -
> -static void tegra_pcie_free_resources(struct tegra_pcie *pcie)
> -{
> -	struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
> -	struct list_head *windows = &host->windows;
> -
> -	pci_unmap_iospace(&pcie->pio);
> -	pci_free_resource_list(windows);
> -}
> -
>  static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
>  {
>  	struct tegra_pcie *pcie = pdev->bus->sysdata;
> @@ -909,36 +867,49 @@ static irqreturn_t tegra_pcie_isr(int irq, void *arg)
>   */
>  static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
>  {
> -	u32 fpci_bar, size, axi_address;
> +	u32 size;
> +	struct resource_entry *entry;
> +	struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
>  
>  	/* Bar 0: type 1 extended configuration space */
>  	size = resource_size(&pcie->cs);
>  	afi_writel(pcie, pcie->cs.start, AFI_AXI_BAR0_START);
>  	afi_writel(pcie, size >> 12, AFI_AXI_BAR0_SZ);
>  
> -	/* Bar 1: downstream IO bar */
> -	fpci_bar = 0xfdfc0000;
> -	size = resource_size(&pcie->io);
> -	axi_address = pcie->io.start;
> -	afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
> -	afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
> -	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
> -
> -	/* Bar 2: prefetchable memory BAR */
> -	fpci_bar = (((pcie->prefetch.start >> 12) & 0x0fffffff) << 4) | 0x1;
> -	size = resource_size(&pcie->prefetch);
> -	axi_address = pcie->prefetch.start;
> -	afi_writel(pcie, axi_address, AFI_AXI_BAR2_START);
> -	afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ);
> -	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR2);
> -
> -	/* Bar 3: non prefetchable memory BAR */
> -	fpci_bar = (((pcie->mem.start >> 12) & 0x0fffffff) << 4) | 0x1;
> -	size = resource_size(&pcie->mem);
> -	axi_address = pcie->mem.start;
> -	afi_writel(pcie, axi_address, AFI_AXI_BAR3_START);
> -	afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ);
> -	afi_writel(pcie, fpci_bar, AFI_FPCI_BAR3);
> +	resource_list_for_each_entry(entry, &bridge->windows) {
> +		u32 fpci_bar, axi_address;
> +		struct resource *res = entry->res;
> +
> +		size = resource_size(res);
> +
> +		switch (resource_type(res)) {
> +		case IORESOURCE_IO:
> +			/* Bar 1: downstream IO bar */
> +			fpci_bar = 0xfdfc0000;
> +			axi_address = pci_pio_to_address(res->start);
> +			afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
> +			afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
> +			afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
> +			break;
> +		case IORESOURCE_MEM:
> +			fpci_bar = (((res->start >> 12) & 0x0fffffff) << 4) | 0x1;
> +			axi_address = res->start;
> +
> +			if (res->flags & IORESOURCE_PREFETCH) {
> +				/* Bar 2: prefetchable memory BAR */
> +				afi_writel(pcie, axi_address, AFI_AXI_BAR2_START);
> +				afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ);
> +				afi_writel(pcie, fpci_bar, AFI_FPCI_BAR2);
> +
> +			} else {
> +				/* Bar 3: non prefetchable memory BAR */
> +				afi_writel(pcie, axi_address, AFI_AXI_BAR3_START);
> +				afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ);
> +				afi_writel(pcie, fpci_bar, AFI_FPCI_BAR3);
> +			}
> +			break;
> +		}
> +	}
>  
>  	/* NULL out the remaining BARs as they are not used */
>  	afi_writel(pcie, 0, AFI_AXI_BAR4_START);
> @@ -2157,76 +2128,10 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
>  	struct device *dev = pcie->dev;
>  	struct device_node *np = dev->of_node, *port;
>  	const struct tegra_pcie_soc *soc = pcie->soc;
> -	struct of_pci_range_parser parser;
> -	struct of_pci_range range;
>  	u32 lanes = 0, mask = 0;
>  	unsigned int lane = 0;
> -	struct resource res;
>  	int err;
>  
> -	if (of_pci_range_parser_init(&parser, np)) {
> -		dev_err(dev, "missing \"ranges\" property\n");
> -		return -EINVAL;
> -	}
> -
> -	for_each_of_pci_range(&parser, &range) {
> -		err = of_pci_range_to_resource(&range, np, &res);
> -		if (err < 0)
> -			return err;
> -
> -		switch (res.flags & IORESOURCE_TYPE_BITS) {
> -		case IORESOURCE_IO:
> -			/* Track the bus -> CPU I/O mapping offset. */
> -			pcie->offset.io = res.start - range.pci_addr;
> -
> -			memcpy(&pcie->pio, &res, sizeof(res));
> -			pcie->pio.name = np->full_name;
> -
> -			/*
> -			 * The Tegra PCIe host bridge uses this to program the
> -			 * mapping of the I/O space to the physical address,
> -			 * so we override the .start and .end fields here that
> -			 * of_pci_range_to_resource() converted to I/O space.
> -			 * We also set the IORESOURCE_MEM type to clarify that
> -			 * the resource is in the physical memory space.
> -			 */
> -			pcie->io.start = range.cpu_addr;
> -			pcie->io.end = range.cpu_addr + range.size - 1;
> -			pcie->io.flags = IORESOURCE_MEM;
> -			pcie->io.name = "I/O";
> -
> -			memcpy(&res, &pcie->io, sizeof(res));
> -			break;
> -
> -		case IORESOURCE_MEM:
> -			/*
> -			 * Track the bus -> CPU memory mapping offset. This
> -			 * assumes that the prefetchable and non-prefetchable
> -			 * regions will be the last of type IORESOURCE_MEM in
> -			 * the ranges property.
> -			 * */
> -			pcie->offset.mem = res.start - range.pci_addr;
> -
> -			if (res.flags & IORESOURCE_PREFETCH) {
> -				memcpy(&pcie->prefetch, &res, sizeof(res));
> -				pcie->prefetch.name = "prefetchable";
> -			} else {
> -				memcpy(&pcie->mem, &res, sizeof(res));
> -				pcie->mem.name = "non-prefetchable";
> -			}
> -			break;
> -		}
> -	}
> -
> -	err = of_pci_parse_bus_range(np, &pcie->busn);
> -	if (err < 0) {
> -		dev_err(dev, "failed to parse ranges property: %d\n", err);
> -		pcie->busn.name = np->name;
> -		pcie->busn.start = 0;
> -		pcie->busn.end = 0xff;
> -		pcie->busn.flags = IORESOURCE_BUS;
> -	}
> -
>  	/* parse root ports */
>  	for_each_child_of_node(np, port) {
>  		struct tegra_pcie_port *rp;
> @@ -2766,6 +2671,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>  	struct pci_host_bridge *host;
>  	struct tegra_pcie *pcie;
>  	struct pci_bus *child;
> +	struct resource *bus;
>  	int err;
>  
>  	host = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
> @@ -2780,6 +2686,12 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>  	INIT_LIST_HEAD(&pcie->ports);
>  	pcie->dev = dev;
>  
> +	err = pci_parse_request_of_pci_ranges(dev, &host->windows, NULL, &bus);
> +	if (err) {
> +		dev_err(dev, "Getting bridge resources failed\n");
> +		return err;
> +	}
> +
>  	err = tegra_pcie_parse_dt(pcie);
>  	if (err < 0)
>  		return err;
> @@ -2803,11 +2715,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>  		goto teardown_msi;
>  	}
>  
> -	err = tegra_pcie_request_resources(pcie);
> -	if (err)
> -		goto pm_runtime_put;
> -
> -	host->busnr = pcie->busn.start;
> +	host->busnr = bus->start;
>  	host->dev.parent = &pdev->dev;
>  	host->ops = &tegra_pcie_ops;
>  	host->map_irq = tegra_pcie_map_irq;
> @@ -2816,7 +2724,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>  	err = pci_scan_root_bus_bridge(host);
>  	if (err < 0) {
>  		dev_err(dev, "failed to register host: %d\n", err);
> -		goto free_resources;
> +		goto pm_runtime_put;
>  	}
>  
>  	pci_bus_size_bridges(host->bus);
> @@ -2835,8 +2743,6 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>  
>  	return 0;
>  
> -free_resources:
> -	tegra_pcie_free_resources(pcie);
>  pm_runtime_put:
>  	pm_runtime_put_sync(pcie->dev);
>  	pm_runtime_disable(pcie->dev);
> @@ -2858,7 +2764,6 @@ static int tegra_pcie_remove(struct platform_device *pdev)
>  
>  	pci_stop_root_bus(host->bus);
>  	pci_remove_root_bus(host->bus);
> -	tegra_pcie_free_resources(pcie);
>  	pm_runtime_put_sync(pcie->dev);
>  	pm_runtime_disable(pcie->dev);
>  
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2020-02-24 13:55 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-28 22:51 [PATCH] PCI: tegra: Use pci_parse_request_of_pci_ranges() Rob Herring
2019-10-30 14:51 ` kbuild test robot
2019-10-30 14:51   ` kbuild test robot
     [not found] ` <20191028225136.22289-1-robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2020-02-21 14:20   ` Lorenzo Pieralisi
2020-02-21 14:20     ` Lorenzo Pieralisi
     [not found]     ` <20200221142051.GB15440-LhTu/34fCX3ZROr8t4l/smS4ubULX0JqMm0uRHvK7Nw@public.gmane.org>
2020-02-22 17:36       ` Vidya Sagar
2020-02-22 17:36         ` Vidya Sagar
     [not found]         ` <c7392952-929a-5be4-ab06-9cf04810290f-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2020-02-24 11:37           ` Lorenzo Pieralisi
2020-02-24 11:37             ` Lorenzo Pieralisi
2020-02-24 13:17   ` Thierry Reding
2020-02-24 13:17     ` Thierry Reding
2020-02-24 13:55   ` Lorenzo Pieralisi
2020-02-24 13:55     ` Lorenzo Pieralisi

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.