all messages for Guix-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
blob 5962e19e0158f1541e8b98da87878eb608f4d1af 3576 bytes (raw)
name: gnu/packages/patches/u-boot-rockchip-inno-usb.patch 	 # note: path name is non-authoritative(*)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
 
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;
 }
 

debug log:

solving 5962e19e01 ...
found 5962e19e01 in https://yhetil.org/guix/4518d704ed2219de4db596ef63867512f571c7e9.1734118924.git.herman@rimm.ee/
found eeb25f4b89 in https://git.savannah.gnu.org/cgit/guix.git
preparing index
index prepared:
100644 eeb25f4b893bed18beadef2dd7b122f4d4552e63	gnu/packages/patches/u-boot-rockchip-inno-usb.patch

applying [1/1] https://yhetil.org/guix/4518d704ed2219de4db596ef63867512f571c7e9.1734118924.git.herman@rimm.ee/
diff --git a/gnu/packages/patches/u-boot-rockchip-inno-usb.patch b/gnu/packages/patches/u-boot-rockchip-inno-usb.patch
index eeb25f4b89..5962e19e01 100644

1:176: space before tab in indent.
 	struct regmap *reg_base;
1:206: space before tab in indent.
 	struct rockchip_usb2phy *priv = dev_get_priv(parent);
Checking patch gnu/packages/patches/u-boot-rockchip-inno-usb.patch...
Applied patch gnu/packages/patches/u-boot-rockchip-inno-usb.patch cleanly.
warning: 2 lines add whitespace errors.

index at:
100644 5962e19e0158f1541e8b98da87878eb608f4d1af	gnu/packages/patches/u-boot-rockchip-inno-usb.patch

(*) Git path names are given by the tree(s) the blob belongs to.
    Blobs themselves have no identifier aside from the hash of its contents.^

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/guix.git

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.