mirror of
https://git.savannah.gnu.org/git/guix.git
synced 2025-01-19 05:57:04 +01:00
56c6466887
* gnu/packages/bootloaders.scm (%u-boot-rockchip-inno-usb-patch, %u-boot-allow-disabling-openssl-patch): Remove variables, move comments. (u-boot)[source]: Use search-patches. * gnu/packages/patches/u-boot-allow-disabling-openssl.patch: Comment. * gnu/packages/patches/u-boot-rockchip-inno-usb.patch: Remove E-Mail metadata. Replace diffstat with comments. Reapply to U-Boot v2024.10. Change-Id: I760a2e81bddfc2a80ef149fe1ac4496cbbd937a0 Signed-off-by: Vagrant Cascadian <vagrant@debian.org>
99 lines
3.5 KiB
Diff
99 lines
3.5 KiB
Diff
From: Icenowy Zheng <icenowy@aosc.io>
|
|
Date: Tue, 6 Apr 2021 23:10:59 +0800
|
|
Subject: [PATCH] phy: rockchip: inno-usb2: fix hang when multiple controllers
|
|
exit
|
|
|
|
The OHCI and EHCI controllers are both bound to the same PHY. They will
|
|
both do init and power_on operations when the controller is brought up
|
|
and both do power_off and exit when the controller is stopped. However,
|
|
the PHY uclass of U-Boot is not as sane as we thought -- they won't
|
|
maintain a status mark for PHYs, and thus the functions of the PHYs
|
|
could be called for multiple times. Calling init/power_on for multiple
|
|
times have no severe problems, however calling power_off/exit for
|
|
multiple times have a problem -- the first exit call will stop the PHY
|
|
clock, and power_off/exit calls after it still trying to write to PHY
|
|
registers. The write operation to PHY registers will fail because clock
|
|
is already stopped.
|
|
|
|
Adapt the count mechanism from phy-sun4i-usb to both init/exit and
|
|
power_on/power_off functions to phy-rockchip-inno-usb2 to fix this
|
|
problem. With this stopping USB controllers (manually or before booting
|
|
a kernel) will work.
|
|
|
|
Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
|
|
Fixes: ac97a9ece14e ("phy: rockchip: Add Rockchip USB2PHY driver")
|
|
Tested-by: Peter Robinson <pbrobinson@gmail.com>
|
|
---
|
|
Fix U-Boot v2020.10 regression, freezing on boot with USB boot enabled:
|
|
https://gitlab.manjaro.org/manjaro-arm/packages/core/uboot-rockpro64/-/issues/4
|
|
|
|
Downloaded from:
|
|
https://patchwork.ozlabs.org/project/uboot/patch/20210406151059.1187379-1-icenowy@aosc.io
|
|
|
|
diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
|
|
index 43f6e020a6a..2086192445d 100644
|
|
--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
|
|
+++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
|
|
@@ -47,6 +47,8 @@ struct rockchip_usb2phy {
|
|
struct regmap *reg_base;
|
|
struct clk phyclk;
|
|
const struct rockchip_usb2phy_cfg *phy_cfg;
|
|
+ int init_count;
|
|
+ int power_on_count;
|
|
};
|
|
|
|
static inline int property_enable(struct regmap *base,
|
|
@@ -98,6 +100,10 @@ static int rockchip_usb2phy_power_on(struct phy *phy)
|
|
struct rockchip_usb2phy *priv = dev_get_priv(parent);
|
|
const struct rockchip_usb2phy_port_cfg *port_cfg = us2phy_get_port(phy);
|
|
|
|
+ priv->power_on_count++;
|
|
+ if (priv->power_on_count != 1)
|
|
+ return 0;
|
|
+
|
|
property_enable(priv->reg_base, &port_cfg->phy_sus, false);
|
|
|
|
/* waiting for the utmi_clk to become stable */
|
|
@@ -112,6 +118,10 @@ static int rockchip_usb2phy_power_off(struct phy *phy)
|
|
struct rockchip_usb2phy *priv = dev_get_priv(parent);
|
|
const struct rockchip_usb2phy_port_cfg *port_cfg = us2phy_get_port(phy);
|
|
|
|
+ priv->power_on_count--;
|
|
+ if (priv->power_on_count != 0)
|
|
+ return 0;
|
|
+
|
|
property_enable(priv->reg_base, &port_cfg->phy_sus, true);
|
|
|
|
return 0;
|
|
@@ -123,6 +133,10 @@ static int rockchip_usb2phy_init(struct phy *phy)
|
|
struct rockchip_usb2phy *priv = dev_get_priv(parent);
|
|
int ret;
|
|
|
|
+ priv->init_count++;
|
|
+ if (priv->init_count != 1)
|
|
+ return 0;
|
|
+
|
|
ret = clk_enable(&priv->phyclk);
|
|
if (ret && ret != -ENOSYS) {
|
|
dev_err(phy->dev, "failed to enable phyclk (ret=%d)\n", ret);
|
|
@@ -137,6 +151,10 @@ static int rockchip_usb2phy_exit(struct phy *phy)
|
|
struct udevice *parent = dev_get_parent(phy->dev);
|
|
struct rockchip_usb2phy *priv = dev_get_priv(parent);
|
|
|
|
+ priv->init_count--;
|
|
+ if (priv->init_count != 0)
|
|
+ return 0;
|
|
+
|
|
clk_disable(&priv->phyclk);
|
|
|
|
return 0;
|
|
@@ -281,6 +299,9 @@ static int rockchip_usb2phy_probe(struct udevice *dev)
|
|
return ret;
|
|
}
|
|
|
|
+ priv->power_on_count = 0;
|
|
+ priv->init_count = 0;
|
|
+
|
|
return 0;
|
|
}
|
|
|