All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mathias Nyman <mathias.nyman@linux.intel.com>
To: Thierry Reding <thierry.reding@gmail.com>,
	Mathias Nyman <mathias.nyman@intel.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Jon Hunter <jonathanh@nvidia.com>, JC Kuo <jckuo@nvidia.com>,
	Nagarjuna Kristam <nkristam@nvidia.com>,
	Sowjanya Komatineni <skomatineni@nvidia.com>,
	linux-usb@vger.kernel.org, linux-tegra@vger.kernel.org
Subject: Re: [PATCH 10/10] usb: host: xhci-tegra: Implement basic ELPG support
Date: Tue, 26 Nov 2019 17:43:15 +0200	[thread overview]
Message-ID: <ceee6a21-c46f-c63f-d38f-78daf7a72969@linux.intel.com> (raw)
In-Reply-To: <20191125123210.1564323-11-thierry.reding@gmail.com>

On 25.11.2019 14.32, Thierry Reding wrote:
> From: Thierry Reding <treding@nvidia.com>
> 
> This implements basic engine-level powergate support which allows the
> XUSB controller to be put into a low power mode on system sleep and get
> it out of that low power mode again on resume.
> 
> Based on work by JC Kuo <jckuo@nvidia.com>.
> 
> Signed-off-by: Thierry Reding <treding@nvidia.com>
> ---
>   drivers/usb/host/xhci-tegra.c | 137 ++++++++++++++++++++++++++++++++--
>   1 file changed, 129 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/usb/host/xhci-tegra.c b/drivers/usb/host/xhci-tegra.c
> index cd3afec408ea..d0e30927a73f 100644
> --- a/drivers/usb/host/xhci-tegra.c
> +++ b/drivers/usb/host/xhci-tegra.c
> @@ -1451,6 +1451,45 @@ static int tegra_xusb_remove(struct platform_device *pdev)
>   }
>   
>   #ifdef CONFIG_PM_SLEEP
> +static bool xhci_hub_ports_suspended(struct xhci_hub *hub)
> +{
> +	struct device *dev = hub->hcd->self.controller;
> +	bool status = true;
> +	unsigned int i;
> +	u32 value;
> +
> +	for (i = 0; i < hub->num_ports; i++) {
> +		value = readl(hub->ports[i]->addr);
> +		if ((value & PORT_PE) == 0)
> +			continue;
> +
> +		if ((value & PORT_PLS_MASK) != XDEV_U3) {
> +			dev_info(dev, "%u-%u isn't suspended: %#010x\n",
> +				 hub->hcd->self.busnum, i + 1, value);
> +			status = false;
> +		}
> +	}
> +
> +	return status;
> +}
> +
> +static int tegra_xusb_check_ports(struct tegra_xusb *tegra)
> +{
> +	struct xhci_hcd *xhci = hcd_to_xhci(tegra->hcd);
> +	unsigned long flags;
> +	int err = 0;
> +
> +	spin_lock_irqsave(&xhci->lock, flags);
> +
> +	if (!xhci_hub_ports_suspended(&xhci->usb2_rhub) ||
> +	    !xhci_hub_ports_suspended(&xhci->usb3_rhub))
> +		err = -EBUSY;
> +
> +	spin_unlock_irqrestore(&xhci->lock, flags);
> +
> +	return err;
> +}
> +
>   static void tegra_xusb_save_context(struct tegra_xusb *tegra)
>   {
>   	const struct tegra_xusb_context_soc *soc = tegra->soc->context;
> @@ -1485,31 +1524,113 @@ static void tegra_xusb_restore_context(struct tegra_xusb *tegra)
>   	}
>   }
>   
> -static int tegra_xusb_suspend(struct device *dev)
> +static int tegra_xusb_enter_elpg(struct tegra_xusb *tegra, bool wakeup)
>   {
> -	struct tegra_xusb *tegra = dev_get_drvdata(dev);
>   	struct xhci_hcd *xhci = hcd_to_xhci(tegra->hcd);
> -	bool wakeup = device_may_wakeup(dev);
> +	u32 value;
>   	int err;
>   
> -	/* TODO: Powergate controller across suspend/resume. */
> +	err = tegra_xusb_check_ports(tegra);
> +	if (err < 0) {
> +		dev_err(tegra->dev, "not all ports suspended: %d\n", err);
> +		return err;
> +	}
> +
>   	err = xhci_suspend(xhci, wakeup);
> -	if (err < 0)
> +	if (err < 0) {
> +		dev_err(tegra->dev, "failed to suspend XHCI: %d\n", err);
>   		return err;
> +	}
>   
>   	tegra_xusb_save_context(tegra);
> +	tegra_xusb_phy_disable(tegra);
> +	tegra_xusb_clk_disable(tegra);
>   
>   	return 0;
>   }
>   
> -static int tegra_xusb_resume(struct device *dev)
> +static int tegra_xusb_exit_elpg(struct tegra_xusb *tegra, bool wakeup)
>   {
> -	struct tegra_xusb *tegra = dev_get_drvdata(dev);
>   	struct xhci_hcd *xhci = hcd_to_xhci(tegra->hcd);
> +	u32 value;
> +	int err;
>   
> +	err = tegra_xusb_clk_enable(tegra);
> +	if (err < 0) {
> +		dev_err(tegra->dev, "failed to enable clocks: %d\n", err);
> +		return err;
> +	}
> +
> +	err = tegra_xusb_phy_enable(tegra);
> +	if (err < 0) {
> +		dev_err(tegra->dev, "failed to enable PHYs: %d\n", err);
> +		goto disable_clk;
> +	}
> +
> +	tegra_xusb_config(tegra);
>   	tegra_xusb_restore_context(tegra);
>   
> -	return xhci_resume(xhci, false);
> +	err = tegra_xusb_load_firmware(tegra);
> +	if (err < 0) {
> +		dev_err(tegra->dev, "failed to load firmware: %d\n", err);
> +		goto disable_phy;
> +	}
> +
> +	err = __tegra_xusb_enable_firmware_messages(tegra);
> +	if (err < 0) {
> +		dev_err(tegra->dev, "failed to enable messages: %d\n", err);
> +		goto disable_phy;
> +	}
> +
> +	err = xhci_resume(xhci, true);
> +	if (err < 0) {
> +		dev_err(tegra->dev, "failed to resume XHCI: %d\n", err);
> +		goto disable_phy;
> +	}
> +
> +	return 0;
> +
> +disable_phy:
> +	tegra_xusb_phy_disable(tegra);
> +disable_clk:
> +	tegra_xusb_clk_disable(tegra);
> +	return err;
> +}
> +
> +static int tegra_xusb_suspend(struct device *dev)
> +{
> +	struct tegra_xusb *tegra = dev_get_drvdata(dev);
> +	bool wakeup = device_may_wakeup(dev);
> +	int err;
> +
> +	synchronize_irq(tegra->mbox_irq);
> +
> +	mutex_lock(&tegra->lock);
> +
> +	err = tegra_xusb_enter_elpg(tegra, wakeup);
> +	if (err < 0)
> +		goto unlock;

Is there some code missing here, or just preparing for some future feature?

> +
> +unlock:
> +	mutex_unlock(&tegra->lock);
> +	return err;
> +}
> +
> +static int tegra_xusb_resume(struct device *dev)
> +{
> +	struct tegra_xusb *tegra = dev_get_drvdata(dev);
> +	bool wakeup = device_may_wakeup(dev);
> +	int err;
> +
> +	mutex_lock(&tegra->lock);
> +
> +	err = tegra_xusb_exit_elpg(tegra, wakeup);
> +	if (err < 0)
> +		goto unlock;
> +
> +unlock:
> +	mutex_unlock(&tegra->lock);
> +	return err;
>   }
>   #endif
>   

Whole series looks good to me otherwise.

Let me know if you want me to take this as is, or if you are planning on making a second version

Thanks
Mathias

  reply	other threads:[~2019-11-26 15:41 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-25 12:32 [PATCH 00/10] usb: host: xhci-tegra: Implement basic ELPG support Thierry Reding
2019-11-25 12:32 ` [PATCH 01/10] usb: host: xhci-tegra: Fix "tega" -> "tegra" typo Thierry Reding
2019-11-26  2:50   ` JC Kuo
2019-11-25 12:32 ` [PATCH 02/10] usb: host: xhci-tegra: Separate firmware request and load Thierry Reding
2019-11-25 12:32 ` [PATCH 03/10] usb: host: xhci-tegra: Avoid a fixed duration sleep Thierry Reding
2019-11-25 13:33   ` Mikko Perttunen
2019-11-25 12:32 ` [PATCH 04/10] usb: host: xhci-tegra: Use CNR as firmware ready indicator Thierry Reding
2019-11-25 12:32 ` [PATCH 05/10] usb: host: xhci-tegra: Extract firmware enable helper Thierry Reding
2019-11-25 12:32 ` [PATCH 06/10] usb: host: xhci-tegra: Reuse stored register base address Thierry Reding
2019-11-25 12:32 ` [PATCH 07/10] usb: host: xhci-tegra: Enable runtime PM as late as possible Thierry Reding
2019-11-25 12:32 ` [PATCH 08/10] usb: host: xhci-tegra: Add support for XUSB context save/restore Thierry Reding
2019-11-25 12:32 ` [PATCH 09/10] usb: host: xhci-tegra: Add XUSB controller context Thierry Reding
2019-11-25 12:32 ` [PATCH 10/10] usb: host: xhci-tegra: Implement basic ELPG support Thierry Reding
2019-11-26 15:43   ` Mathias Nyman [this message]
2019-12-06 14:27     ` Thierry Reding

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=ceee6a21-c46f-c63f-d38f-78daf7a72969@linux.intel.com \
    --to=mathias.nyman@linux.intel.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=jckuo@nvidia.com \
    --cc=jonathanh@nvidia.com \
    --cc=linux-tegra@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=mathias.nyman@intel.com \
    --cc=nkristam@nvidia.com \
    --cc=skomatineni@nvidia.com \
    --cc=thierry.reding@gmail.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.