A board I'm working on seems to get its usb->sata bridge in a rather
confused state during reboot, which unfortunately can't be recovered on
the next boot (only hard reset helps).
This seems to be avoidable by turning off vbus, which turns the internal
usb hub off on shutdown.
First patch add the ability to describe vbus regulators for the rockchip
usb phy, second one starts using that on the rock2 square board and
while the final one adds the actual workaround of turning off the phy on
shutdown.
Sjoerd Simons (3):
phy: rockchip-usb: Add vbus regulator support.
ARM: dts: rockchip: rock2: Setup usb vbus-supply
usb: dwc2: Power off the phy on shutdown
.../devicetree/bindings/phy/rockchip-usb-phy.txt | 1 +
arch/arm/boot/dts/rk3288-rock2-square.dts | 8 ++++----
drivers/phy/phy-rockchip-usb.c | 19 +++++++++++++++++++
drivers/usb/dwc2/platform.c | 3 +++
4 files changed, 27 insertions(+), 4 deletions(-)
--
2.11.0
Now that the rockchip usb phy has a vbus-supply property use that to
control the vbus regulator on rock2.
Signed-off-by: Sjoerd Simons <[email protected]>
---
arch/arm/boot/dts/rk3288-rock2-square.dts | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm/boot/dts/rk3288-rock2-square.dts b/arch/arm/boot/dts/rk3288-rock2-square.dts
index a23a94811be8..8ed25e9f60bc 100644
--- a/arch/arm/boot/dts/rk3288-rock2-square.dts
+++ b/arch/arm/boot/dts/rk3288-rock2-square.dts
@@ -125,10 +125,6 @@
gpio = <&gpio0 RK_PB6 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&host_vbus_drv>;
- /* Always on as the rockchip usb phy doesn't have a vbus-supply
- * property
- */
- regulator-always-on;
regulator-name = "vcc_host";
};
@@ -279,6 +275,10 @@
status = "okay";
};
+&usbphy1 {
+ vbus-supply = <&vcc_usb_host>;
+};
+
&usb_host0_ehci {
status = "okay";
};
--
2.11.0
On a board with a usb->sata bridge behind a usb hub, the bridge only
appears on cold boot and becomes non-functional after a reboot. Testing
thusfar shows that it gets confused during reboot if the usb hub is left
on (Interestingly a similar setup without the usb hub in between doesn't
have the issue). This can be avoided by turning off the phy (thus vbus)
during shutdown, which turns off the usb hub.
For devices where this isn't required, powering down the phy is harmless
so we can do this unconditionally.
Signed-off-by: Sjoerd Simons <[email protected]>
---
drivers/usb/dwc2/platform.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c
index 9564bc76c56f..b5bbc433c94d 100644
--- a/drivers/usb/dwc2/platform.c
+++ b/drivers/usb/dwc2/platform.c
@@ -348,6 +348,9 @@ static void dwc2_driver_shutdown(struct platform_device *dev)
{
struct dwc2_hsotg *hsotg = platform_get_drvdata(dev);
+ if (hsotg->phy)
+ phy_power_off(hsotg->phy);
+
disable_irq(hsotg->irq);
}
--
2.11.0
On rockchip devices vbus is supplied by a separate power supply, often
through a regulator. Add support for describing the the regulator in
device-tree following the same convention as several other usb phy's.
Signed-off-by: Sjoerd Simons <[email protected]>
---
.../devicetree/bindings/phy/rockchip-usb-phy.txt | 1 +
drivers/phy/phy-rockchip-usb.c | 19 +++++++++++++++++++
2 files changed, 20 insertions(+)
diff --git a/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt b/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt
index 57dc388e2fa2..4ed569046daf 100644
--- a/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt
+++ b/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt
@@ -30,6 +30,7 @@ Optional Properties:
- reset-names: Only allow the following entries:
- phy-reset
- resets: Must contain an entry for each entry in reset-names.
+- vbus-supply: power-supply phandle for vbus power source
Example:
diff --git a/drivers/phy/phy-rockchip-usb.c b/drivers/phy/phy-rockchip-usb.c
index 734987fa0ad7..3378eeb7a562 100644
--- a/drivers/phy/phy-rockchip-usb.c
+++ b/drivers/phy/phy-rockchip-usb.c
@@ -66,6 +66,7 @@ struct rockchip_usb_phy {
struct phy *phy;
bool uart_enabled;
struct reset_control *reset;
+ struct regulator *vbus;
};
static int rockchip_usb_phy_power(struct rockchip_usb_phy *phy,
@@ -88,6 +89,9 @@ static void rockchip_usb_phy480m_disable(struct clk_hw *hw)
struct rockchip_usb_phy,
clk480m_hw);
+ if (phy->vbus)
+ regulator_disable(phy->vbus);
+
/* Power down usb phy analog blocks by set siddq 1 */
rockchip_usb_phy_power(phy, 1);
}
@@ -143,6 +147,14 @@ static int rockchip_usb_phy_power_on(struct phy *_phy)
if (phy->uart_enabled)
return -EBUSY;
+ if (phy->vbus) {
+ int ret;
+
+ ret = regulator_enable(phy->vbus);
+ if (ret)
+ return ret;
+ }
+
return clk_prepare_enable(phy->clk480m);
}
@@ -268,6 +280,13 @@ static int rockchip_usb_phy_init(struct rockchip_usb_phy_base *base,
}
phy_set_drvdata(rk_phy->phy, rk_phy);
+ rk_phy->vbus = devm_regulator_get_optional(&rk_phy->phy->dev, "vbus");
+ if (IS_ERR(rk_phy->vbus)) {
+ if (PTR_ERR(rk_phy->vbus) == -EPROBE_DEFER)
+ return PTR_ERR(rk_phy->vbus);
+ rk_phy->vbus = NULL;
+ }
+
/*
* When acting as uart-pipe, just keep clock on otherwise
* only power up usb phy when it use, so disable it when init
--
2.11.0
On Wednesday 05 April 2017 07:36 PM, Sjoerd Simons wrote:
> On rockchip devices vbus is supplied by a separate power supply, often
> through a regulator. Add support for describing the the regulator in
> device-tree following the same convention as several other usb phy's.
>
merged, thanks.
-Kishon
> Signed-off-by: Sjoerd Simons <[email protected]>
> ---
>
> .../devicetree/bindings/phy/rockchip-usb-phy.txt | 1 +
> drivers/phy/phy-rockchip-usb.c | 19 +++++++++++++++++++
> 2 files changed, 20 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt b/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt
> index 57dc388e2fa2..4ed569046daf 100644
> --- a/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt
> +++ b/Documentation/devicetree/bindings/phy/rockchip-usb-phy.txt
> @@ -30,6 +30,7 @@ Optional Properties:
> - reset-names: Only allow the following entries:
> - phy-reset
> - resets: Must contain an entry for each entry in reset-names.
> +- vbus-supply: power-supply phandle for vbus power source
>
> Example:
>
> diff --git a/drivers/phy/phy-rockchip-usb.c b/drivers/phy/phy-rockchip-usb.c
> index 734987fa0ad7..3378eeb7a562 100644
> --- a/drivers/phy/phy-rockchip-usb.c
> +++ b/drivers/phy/phy-rockchip-usb.c
> @@ -66,6 +66,7 @@ struct rockchip_usb_phy {
> struct phy *phy;
> bool uart_enabled;
> struct reset_control *reset;
> + struct regulator *vbus;
> };
>
> static int rockchip_usb_phy_power(struct rockchip_usb_phy *phy,
> @@ -88,6 +89,9 @@ static void rockchip_usb_phy480m_disable(struct clk_hw *hw)
> struct rockchip_usb_phy,
> clk480m_hw);
>
> + if (phy->vbus)
> + regulator_disable(phy->vbus);
> +
> /* Power down usb phy analog blocks by set siddq 1 */
> rockchip_usb_phy_power(phy, 1);
> }
> @@ -143,6 +147,14 @@ static int rockchip_usb_phy_power_on(struct phy *_phy)
> if (phy->uart_enabled)
> return -EBUSY;
>
> + if (phy->vbus) {
> + int ret;
> +
> + ret = regulator_enable(phy->vbus);
> + if (ret)
> + return ret;
> + }
> +
> return clk_prepare_enable(phy->clk480m);
> }
>
> @@ -268,6 +280,13 @@ static int rockchip_usb_phy_init(struct rockchip_usb_phy_base *base,
> }
> phy_set_drvdata(rk_phy->phy, rk_phy);
>
> + rk_phy->vbus = devm_regulator_get_optional(&rk_phy->phy->dev, "vbus");
> + if (IS_ERR(rk_phy->vbus)) {
> + if (PTR_ERR(rk_phy->vbus) == -EPROBE_DEFER)
> + return PTR_ERR(rk_phy->vbus);
> + rk_phy->vbus = NULL;
> + }
> +
> /*
> * When acting as uart-pipe, just keep clock on otherwise
> * only power up usb phy when it use, so disable it when init
>
Am Mittwoch, 5. April 2017, 16:06:11 CEST schrieb Sjoerd Simons:
> Now that the rockchip usb phy has a vbus-supply property use that to
> control the vbus regulator on rock2.
>
> Signed-off-by: Sjoerd Simons <[email protected]>
I've queued this for 4.13 .
Not eligible for 4.12, as the patch alone (when testing my tree or armsoc)
would regress the sata-bridge, due to the regulator-always-on going away.
Heiko