All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mikko Perttunen <cyndis@kapsi.fi>
To: Manikanta Maddireddy <mmaddireddy@nvidia.com>,
	thierry.reding@gmail.com, jonathanh@nvidia.com,
	robh+dt@kernel.org, frowand.list@gmail.com, bhelgaas@google.com,
	rjw@rjwysocki.net, tglx@linutronix.de
Cc: vidyas@nvidia.com, kthota@nvidia.com,
	linux-tegra@vger.kernel.org, devicetree@vger.kernel.org,
	linux-pci@vger.kernel.org, linux-pm@vger.kernel.org
Subject: Re: [PATCH V2 6/9] PCI: tegra: free resources on probe failure
Date: Wed, 29 Nov 2017 13:59:39 +0200	[thread overview]
Message-ID: <2c8b33f4-1524-cd0f-05f5-15f87bf59e31@kapsi.fi> (raw)
In-Reply-To: <1511638333-22951-7-git-send-email-mmaddireddy@nvidia.com>

On 25.11.2017 21:32, Manikanta Maddireddy wrote:
> tegra_pcie_probe() can fail in multiple instances, this patch takes care
> of freeing the resources which are allocated before probe fail.
>
> Signed-off-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
> ---
> V2:
> * no change in this patch
>
>  drivers/pci/host/pci-tegra.c | 102 ++++++++++++++++++++++++++++++++++++-------
>  1 file changed, 86 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
> index e9b3ff95e259..7f7b8c9c1e84 100644
> --- a/drivers/pci/host/pci-tegra.c
> +++ b/drivers/pci/host/pci-tegra.c
> @@ -701,14 +701,25 @@ static int tegra_pcie_request_resources(struct tegra_pcie *pcie)
>  	pci_add_resource(windows, &pcie->busn);
>
>  	err = devm_request_pci_bus_resources(dev, windows);
> -	if (err < 0)
> +	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 pci_host_bridge *host = pci_find_host_bridge(pdev->bus);
> @@ -1109,29 +1120,40 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie)
>  	return 0;
>  }
>
> -static void tegra_pcie_power_off(struct tegra_pcie *pcie)
> +static void tegra_pcie_disable_controller(struct tegra_pcie *pcie)
>  {
>  	struct device *dev = pcie->dev;
>  	const struct tegra_pcie_soc *soc = pcie->soc;
>  	int err;
>
> -	/* TODO: disable and unprepare clocks? */
> -
>  	if (soc->program_uphy) {
>  		err = tegra_pcie_phy_power_off(pcie);
>  		if (err < 0)
>  			dev_err(dev, "failed to power off PHY(s): %d\n", err);
>  	}
> +}
> +
> +static void tegra_pcie_power_off(struct tegra_pcie *pcie)
> +{
> +	struct device *dev = pcie->dev;
> +	const struct tegra_pcie_soc *soc = pcie->soc;
> +	int err;
>
>  	reset_control_assert(pcie->afi_rst);
>  	reset_control_assert(pcie->pex_rst);
>
> -	if (!dev->pm_domain)
> -		tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
> +	clk_disable_unprepare(pcie->pll_e);
> +	if (soc->has_cml_clk)
> +		clk_disable_unprepare(pcie->cml_clk);
> +	clk_disable_unprepare(pcie->afi_clk);
> +	clk_disable_unprepare(pcie->pex_clk);
>
>  	err = regulator_bulk_disable(pcie->num_supplies, pcie->supplies);
>  	if (err < 0)
>  		dev_warn(dev, "failed to disable regulators: %d\n", err);
> +
> +	if (!dev->pm_domain)
> +		tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
>  }
>
>  static int tegra_pcie_power_on(struct tegra_pcie *pcie)
> @@ -1262,6 +1284,15 @@ static int tegra_pcie_phys_get_legacy(struct tegra_pcie *pcie)
>  	return 0;
>  }
>
> +static void tegra_pcie_phys_put_legacy(struct tegra_pcie *pcie)
> +{
> +	int err;
> +
> +	err = phy_exit(pcie->phy);
> +	if (err < 0)
> +		dev_err(pcie->dev, "failed to teardown PHY: %d\n", err);
> +}
> +
>  static struct phy *devm_of_phy_optional_get_index(struct device *dev,
>  						  struct device_node *np,
>  						  const char *consumer,
> @@ -1315,6 +1346,19 @@ static int tegra_pcie_port_get_phys(struct tegra_pcie_port *port)
>  	return 0;
>  }
>
> +static void tegra_pcie_port_put_phys(struct tegra_pcie_port *port)
> +{
> +	struct device *dev = port->pcie->dev;
> +	unsigned int i;
> +	int err;
> +
> +	for (i = 0; i < port->lanes; i++) {
> +		err = phy_exit(port->phys[i]);
> +		if (err < 0)
> +			dev_err(dev, "failed to teardown PHY#%u: %d\n", i, err);
> +	}
> +}
> +
>  static int tegra_pcie_phys_get(struct tegra_pcie *pcie)
>  {
>  	const struct tegra_pcie_soc *soc = pcie->soc;
> @@ -1334,6 +1378,19 @@ static int tegra_pcie_phys_get(struct tegra_pcie *pcie)
>  	return 0;
>  }
>
> +static void tegra_pcie_phys_put(struct tegra_pcie *pcie)
> +{
> +	const struct tegra_pcie_soc *soc = pcie->soc;
> +	struct device_node *np = pcie->dev->of_node;
> +	struct tegra_pcie_port *port;
> +
> +	if (!soc->has_gen2 || of_find_property(np, "phys", NULL) != NULL)
> +		tegra_pcie_phys_put_legacy(pcie);

I think it would be nicer to just check if legacy_phy is true, since 
tegra_pcie_phys_get_legacy sets it. That way we don't need to have the 
complicated check in two places.

Mikko

> +
> +	list_for_each_entry(port, &pcie->ports, list)
> +		tegra_pcie_port_put_phys(port);
> +}
> +
>  static int tegra_pcie_get_resources(struct tegra_pcie *pcie)
>  {
>  	struct device *dev = pcie->dev;
> @@ -1366,7 +1423,7 @@ static int tegra_pcie_get_resources(struct tegra_pcie *pcie)
>  	err = tegra_pcie_power_on(pcie);
>  	if (err) {
>  		dev_err(dev, "failed to power up: %d\n", err);
> -		return err;
> +		goto phys_put;
>  	}
>
>  	pads = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pads");
> @@ -1424,25 +1481,23 @@ static int tegra_pcie_get_resources(struct tegra_pcie *pcie)
>
>  poweroff:
>  	tegra_pcie_power_off(pcie);
> +phys_put:
> +	if (soc->program_uphy)
> +		tegra_pcie_phys_put(pcie);
>  	return err;
>  }
>
>  static int tegra_pcie_put_resources(struct tegra_pcie *pcie)
>  {
> -	struct device *dev = pcie->dev;
>  	const struct tegra_pcie_soc *soc = pcie->soc;
> -	int err;
>
>  	if (pcie->irq > 0)
>  		free_irq(pcie->irq, pcie);
>
>  	tegra_pcie_power_off(pcie);
>
> -	if (soc->program_uphy) {
> -		err = phy_exit(pcie->phy);
> -		if (err < 0)
> -			dev_err(dev, "failed to teardown PHY: %d\n", err);
> -	}
> +	if (soc->program_uphy)
> +		tegra_pcie_phys_put(pcie);
>
>  	return 0;
>  }
> @@ -2371,6 +2426,16 @@ static void tegra_pcie_enable_ports(struct tegra_pcie *pcie)
>  	}
>  }
>
> +static void tegra_pcie_disable_ports(struct tegra_pcie *pcie)
> +{
> +	struct tegra_pcie_port *port, *tmp;
> +
> +	reset_control_assert(pcie->pcie_xrst);
> +
> +	list_for_each_entry_safe(port, tmp, &pcie->ports, list)
> +		tegra_pcie_port_disable(port);
> +}
> +
>  static void tegra_pcie_change_link_speed(struct tegra_pcie *pcie,
>  					 struct pci_dev *pci_dev)
>  {
> @@ -2691,7 +2756,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>
>  	err = tegra_pcie_request_resources(pcie);
>  	if (err)
> -		goto put_resources;
> +		goto disable_controller;
>
>  	/* setup the AFI address translations */
>  	tegra_pcie_setup_translations(pcie);
> @@ -2700,7 +2765,7 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>  		err = tegra_pcie_enable_msi(pcie);
>  		if (err < 0) {
>  			dev_err(dev, "failed to enable MSI support: %d\n", err);
> -			goto put_resources;
> +			goto free_resources;
>  		}
>  	}
>
> @@ -2741,6 +2806,11 @@ static int tegra_pcie_probe(struct platform_device *pdev)
>  disable_msi:
>  	if (IS_ENABLED(CONFIG_PCI_MSI))
>  		tegra_pcie_disable_msi(pcie);
> +	tegra_pcie_disable_ports(pcie);
> +free_resources:
> +	tegra_pcie_free_resources(pcie);
> +disable_controller:
> +	tegra_pcie_disable_controller(pcie);
>  put_resources:
>  	tegra_pcie_put_resources(pcie);
>  	return err;
>

  reply	other threads:[~2017-11-29 11:59 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-25 19:32 [PATCH V2 0/9] Add loadable kernel module and power management support Manikanta Maddireddy
2017-11-25 19:32 ` Manikanta Maddireddy
2017-11-25 19:32 ` [PATCH V2 3/9] ARM: tegra: Export tegra_cpuidle_pcie_irqs_in_use() Manikanta Maddireddy
2017-11-25 19:32   ` Manikanta Maddireddy
     [not found] ` <1511638333-22951-1-git-send-email-mmaddireddy-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2017-11-25 19:32   ` [PATCH V2 1/9] genirq: Export irq_set_msi_desc() Manikanta Maddireddy
2017-11-25 19:32     ` Manikanta Maddireddy
2017-11-25 19:32   ` [PATCH V2 2/9] of: Export of_pci_range_to_resource() Manikanta Maddireddy
2017-11-25 19:32     ` Manikanta Maddireddy
     [not found]     ` <1511638333-22951-3-git-send-email-mmaddireddy-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2017-11-26 22:31       ` Rob Herring
2017-11-26 22:31         ` Rob Herring
2017-11-25 19:32   ` [PATCH V2 4/9] PCI: Export pci_find_host_bridge() Manikanta Maddireddy
2017-11-25 19:32     ` Manikanta Maddireddy
2017-11-29 17:35     ` Christoph Hellwig
2017-11-25 19:32   ` [PATCH V2 5/9] PCI: Export pci_flags Manikanta Maddireddy
2017-11-25 19:32     ` Manikanta Maddireddy
2017-11-29 17:01     ` Bjorn Helgaas
     [not found]       ` <20171129170133.GC6469-1RhO1Y9PlrlHTL0Zs8A6p5iNqAH0jzoTYJqu5kTmcBRl57MIdRCFDg@public.gmane.org>
2017-11-30 10:24         ` Lorenzo Pieralisi
2017-11-30 10:24           ` Lorenzo Pieralisi
2017-11-30 18:42           ` Bjorn Helgaas
2017-11-30 18:42             ` Bjorn Helgaas
2017-11-30 19:38             ` Manikanta Maddireddy
2017-11-30 19:38               ` Manikanta Maddireddy
2017-11-25 19:32   ` [PATCH V2 6/9] PCI: tegra: free resources on probe failure Manikanta Maddireddy
2017-11-25 19:32     ` Manikanta Maddireddy
2017-11-29 11:59     ` Mikko Perttunen [this message]
2017-11-29 17:02     ` Bjorn Helgaas
2017-11-25 19:32 ` [PATCH V2 7/9] PCI: tegra: Add loadable kernel module support Manikanta Maddireddy
2017-11-25 19:32   ` Manikanta Maddireddy
     [not found]   ` <1511638333-22951-8-git-send-email-mmaddireddy-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2017-11-29 12:01     ` Mikko Perttunen
2017-11-29 12:01       ` Mikko Perttunen
2017-11-30 18:39       ` Manikanta Maddireddy
2017-11-30 18:39         ` Manikanta Maddireddy
2017-11-25 19:32 ` [PATCH V2 8/9] PCI: tegra: Broadcast PME_turn_Off message before link goes to L2 Manikanta Maddireddy
2017-11-25 19:32   ` Manikanta Maddireddy
2017-11-29 12:18   ` Mikko Perttunen
2017-12-01  8:51     ` Mikko Perttunen
     [not found]   ` <1511638333-22951-9-git-send-email-mmaddireddy-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2017-11-29 16:51     ` Bjorn Helgaas
2017-11-29 16:51       ` Bjorn Helgaas
2017-11-30 18:43       ` Manikanta Maddireddy
2017-11-30 18:43         ` Manikanta Maddireddy
2017-11-25 19:32 ` [PATCH V2 9/9] PCI: tegra: Add power management support Manikanta Maddireddy
2017-11-25 19:32   ` Manikanta Maddireddy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2c8b33f4-1524-cd0f-05f5-15f87bf59e31@kapsi.fi \
    --to=cyndis@kapsi.fi \
    --cc=bhelgaas@google.com \
    --cc=devicetree@vger.kernel.org \
    --cc=frowand.list@gmail.com \
    --cc=jonathanh@nvidia.com \
    --cc=kthota@nvidia.com \
    --cc=linux-pci@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=linux-tegra@vger.kernel.org \
    --cc=mmaddireddy@nvidia.com \
    --cc=rjw@rjwysocki.net \
    --cc=robh+dt@kernel.org \
    --cc=tglx@linutronix.de \
    --cc=thierry.reding@gmail.com \
    --cc=vidyas@nvidia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.