All of lore.kernel.org
 help / color / mirror / Atom feed
From: JC Kuo <jckuo@nvidia.com>
To: <gregkh@linuxfoundation.org>, <thierry.reding@gmail.com>,
	<robh@kernel.org>, <jonathanh@nvidia.com>, <kishon@ti.com>
Cc: <linux-tegra@vger.kernel.org>, <linux-usb@vger.kernel.org>,
	<linux-kernel@vger.kernel.org>, <devicetree@vger.kernel.org>,
	<nkristam@nvidia.com>, JC Kuo <jckuo@nvidia.com>,
	Thierry Reding <treding@nvidia.com>
Subject: [PATCH v6 12/15] phy: tegra: xusb: Tegra210 host mode VBUS control
Date: Tue, 19 Jan 2021 16:55:43 +0800	[thread overview]
Message-ID: <20210119085546.725005-13-jckuo@nvidia.com> (raw)
In-Reply-To: <20210119085546.725005-1-jckuo@nvidia.com>

To support XUSB host controller ELPG, this commit moves VBUS control
.phy_power_on()/.phy_power_off() to .phy_init()/.phy_exit().
When XUSB host controller enters ELPG, host driver invokes
.phy_power_off(), VBUS should remain ON so that USB devices will not
disconnect. VBUS can be turned OFF when host driver invokes
.phy_exit() which indicates disabling a USB port.

Signed-off-by: JC Kuo <jckuo@nvidia.com>
Acked-by: Thierry Reding <treding@nvidia.com>
---
v6:
   no change
v5:
   no change
v4:
   no change
v3:
   new, was a part of "phy: tegra: xusb: Add wake/sleepwalk for Tegra210"

 drivers/phy/tegra/xusb-tegra210.c | 52 ++++++++++++++++++++++++-------
 1 file changed, 40 insertions(+), 12 deletions(-)

diff --git a/drivers/phy/tegra/xusb-tegra210.c b/drivers/phy/tegra/xusb-tegra210.c
index 8af73ba78ad7..9d39f812fb43 100644
--- a/drivers/phy/tegra/xusb-tegra210.c
+++ b/drivers/phy/tegra/xusb-tegra210.c
@@ -1819,8 +1819,25 @@ static int tegra210_usb2_phy_init(struct phy *phy)
 {
 	struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
 	struct tegra_xusb_padctl *padctl = lane->pad->padctl;
+	unsigned int index = lane->index;
+	struct tegra_xusb_usb2_port *port;
+	int err;
 	u32 value;
 
+	port = tegra_xusb_find_usb2_port(padctl, index);
+	if (!port) {
+		dev_err(&phy->dev, "no port found for USB2 lane %u\n", index);
+		return -ENODEV;
+	}
+
+	if (port->supply && port->mode == USB_DR_MODE_HOST) {
+		err = regulator_enable(port->supply);
+		if (err)
+			return err;
+	}
+
+	mutex_lock(&padctl->lock);
+
 	value = padctl_readl(padctl, XUSB_PADCTL_USB2_PAD_MUX);
 	value &= ~(XUSB_PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_MASK <<
 		   XUSB_PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_SHIFT);
@@ -1828,11 +1845,30 @@ static int tegra210_usb2_phy_init(struct phy *phy)
 		 XUSB_PADCTL_USB2_PAD_MUX_USB2_BIAS_PAD_SHIFT;
 	padctl_writel(padctl, value, XUSB_PADCTL_USB2_PAD_MUX);
 
+	mutex_unlock(&padctl->lock);
+
 	return 0;
 }
 
 static int tegra210_usb2_phy_exit(struct phy *phy)
 {
+	struct tegra_xusb_lane *lane = phy_get_drvdata(phy);
+	struct tegra_xusb_padctl *padctl = lane->pad->padctl;
+	struct tegra_xusb_usb2_port *port;
+	int err;
+
+	port = tegra_xusb_find_usb2_port(padctl, lane->index);
+	if (!port) {
+		dev_err(&phy->dev, "no port found for USB2 lane %u\n", lane->index);
+		return -ENODEV;
+	}
+
+	if (port->supply && port->mode == USB_DR_MODE_HOST) {
+		err = regulator_disable(port->supply);
+		if (err)
+			return err;
+	}
+
 	return 0;
 }
 
@@ -1953,6 +1989,8 @@ static int tegra210_usb2_phy_power_on(struct phy *phy)
 
 	priv = to_tegra210_xusb_padctl(padctl);
 
+	mutex_lock(&padctl->lock);
+
 	if (port->usb3_port_fake != -1) {
 		value = padctl_readl(padctl, XUSB_PADCTL_SS_PORT_MAP);
 		value &= ~XUSB_PADCTL_SS_PORT_MAP_PORTX_MAP_MASK(
@@ -2046,14 +2084,6 @@ static int tegra210_usb2_phy_power_on(struct phy *phy)
 	padctl_writel(padctl, value,
 		      XUSB_PADCTL_USB2_BATTERY_CHRG_OTGPADX_CTL1(index));
 
-	if (port->supply && port->mode == USB_DR_MODE_HOST) {
-		err = regulator_enable(port->supply);
-		if (err)
-			return err;
-	}
-
-	mutex_lock(&padctl->lock);
-
 	if (pad->enable > 0) {
 		pad->enable++;
 		mutex_unlock(&padctl->lock);
@@ -2062,7 +2092,7 @@ static int tegra210_usb2_phy_power_on(struct phy *phy)
 
 	err = clk_prepare_enable(pad->clk);
 	if (err)
-		goto disable_regulator;
+		goto out;
 
 	value = padctl_readl(padctl, XUSB_PADCTL_USB2_BIAS_PAD_CTL1);
 	value &= ~((XUSB_PADCTL_USB2_BIAS_PAD_CTL1_TRK_START_TIMER_MASK <<
@@ -2094,8 +2124,7 @@ static int tegra210_usb2_phy_power_on(struct phy *phy)
 
 	return 0;
 
-disable_regulator:
-	regulator_disable(port->supply);
+out:
 	mutex_unlock(&padctl->lock);
 	return err;
 }
@@ -2154,7 +2183,6 @@ static int tegra210_usb2_phy_power_off(struct phy *phy)
 	padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL0);
 
 out:
-	regulator_disable(port->supply);
 	mutex_unlock(&padctl->lock);
 	return 0;
 }
-- 
2.25.1


  parent reply	other threads:[~2021-01-19  9:03 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-19  8:55 [PATCH v6 00/15] Tegra XHCI controller ELPG support JC Kuo
2021-01-19  8:55 ` [PATCH v6 01/15] clk: tegra: Add PLLE HW power sequencer control JC Kuo
2021-01-19 14:11   ` Thierry Reding
2021-02-11  3:06   ` Stephen Boyd
2021-01-19  8:55 ` [PATCH v6 02/15] clk: tegra: Don't enable PLLE HW sequencer at init JC Kuo
2021-01-19 14:12   ` Thierry Reding
2021-02-11  3:06   ` Stephen Boyd
2021-01-19  8:55 ` [PATCH v6 03/15] phy: tegra: xusb: Move usb3 port init for Tegra210 JC Kuo
2021-01-19  8:55 ` [PATCH v6 04/15] phy: tegra: xusb: tegra210: Do not reset UPHY PLL JC Kuo
2021-01-19 13:52   ` Thierry Reding
2021-01-20  1:42     ` JC Kuo
2021-01-19  8:55 ` [PATCH v6 05/15] phy: tegra: xusb: Rearrange UPHY init on Tegra210 JC Kuo
2021-01-19  8:55 ` [PATCH v6 06/15] phy: tegra: xusb: Add Tegra210 lane_iddq operation JC Kuo
2021-01-19  8:55 ` [PATCH v6 07/15] phy: tegra: xusb: Add sleepwalk and suspend/resume JC Kuo
2021-01-19 13:54   ` Thierry Reding
2021-01-19  8:55 ` [PATCH v6 08/15] soc/tegra: pmc: Provide USB sleepwalk register map JC Kuo
2021-01-19  8:55 ` [PATCH v6 09/15] arm64: tegra210: XUSB PADCTL add "nvidia,pmc" prop JC Kuo
2021-01-19  8:55 ` [PATCH v6 10/15] dt-bindings: phy: tegra-xusb: Add nvidia,pmc prop JC Kuo
2021-01-19  8:55 ` [PATCH v6 11/15] phy: tegra: xusb: Add wake/sleepwalk for Tegra210 JC Kuo
2021-01-19 13:58   ` Thierry Reding
2021-01-19  8:55 ` JC Kuo [this message]
2021-01-19  8:55 ` [PATCH v6 13/15] phy: tegra: xusb: Add wake/sleepwalk for Tegra186 JC Kuo
2021-01-19 13:59   ` Thierry Reding
2021-01-19  8:55 ` [PATCH v6 14/15] usb: host: xhci-tegra: Unlink power domain devices JC Kuo
2021-01-19 14:04   ` Thierry Reding
2021-01-19  8:55 ` [PATCH v6 15/15] xhci: tegra: Enable ELPG for runtime/system PM JC Kuo
2021-01-19 14:04   ` Thierry Reding
2021-01-19 14:07 ` [PATCH v6 00/15] Tegra XHCI controller ELPG support 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=20210119085546.725005-13-jckuo@nvidia.com \
    --to=jckuo@nvidia.com \
    --cc=devicetree@vger.kernel.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=jonathanh@nvidia.com \
    --cc=kishon@ti.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tegra@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=nkristam@nvidia.com \
    --cc=robh@kernel.org \
    --cc=thierry.reding@gmail.com \
    --cc=treding@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.