347aaba0750054c1dfc214d9d8e4bbc32412648b
[openwrt/staging/blocktrron.git] /
1 From 1848a504379531eb726d29b355f9038d194e8430 Mon Sep 17 00:00:00 2001
2 From: Alex Shumsky <alexthreed@gmail.com>
3 Date: Thu, 3 Jul 2025 09:04:48 +0300
4 Subject: [PATCH] rockchip: rockchip-inno-usb2: Fix Synchronous Abort on usb
5 start
6
7 Fix NULL pointer dereference that happen when rockchip-inno-usb2 clock
8 enabled before device probe. This early clock enable call happen in process
9 of parent clock activation added in ac30d90f3367.
10
11 Fixes: 229218373c22 ("phy: rockchip-inno-usb2: Add support for clkout_ctl_phy").
12 Fixes: ac30d90f3367 ("clk: Ensure the parent clocks are enabled while reparenting")
13 Co-authored-by: Jonas Karlman <jonas@kwiboo.se>
14 Signed-off-by: Alex Shumsky <alexthreed@gmail.com>
15 Reviewed-by: Jonas Karlman <jonas@kwiboo.se>
16 Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
17 ---
18 drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 19 ++++++++++++++-----
19 1 file changed, 14 insertions(+), 5 deletions(-)
20
21 --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
22 +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c
23 @@ -167,20 +167,27 @@ static struct phy_ops rockchip_usb2phy_o
24 .of_xlate = rockchip_usb2phy_of_xlate,
25 };
26
27 -static void rockchip_usb2phy_clkout_ctl(struct clk *clk, struct regmap **base,
28 - const struct usb2phy_reg **clkout_ctl)
29 +static int rockchip_usb2phy_clkout_ctl(struct clk *clk, struct regmap **base,
30 + const struct usb2phy_reg **clkout_ctl)
31 {
32 struct udevice *parent = dev_get_parent(clk->dev);
33 struct rockchip_usb2phy *priv = dev_get_priv(parent);
34 const struct rockchip_usb2phy_cfg *phy_cfg = priv->phy_cfg;
35
36 - if (priv->phy_cfg->clkout_ctl_phy.enable) {
37 + // phy_cfg can be NULL if this function called before probe (when parent
38 + // clocks are enabled)
39 + if (!phy_cfg)
40 + return -EINVAL;
41 +
42 + if (phy_cfg->clkout_ctl_phy.enable) {
43 *base = priv->phy_base;
44 *clkout_ctl = &phy_cfg->clkout_ctl_phy;
45 } else {
46 *base = priv->reg_base;
47 *clkout_ctl = &phy_cfg->clkout_ctl;
48 }
49 +
50 + return 0;
51 }
52
53 /**
54 @@ -206,7 +213,8 @@ int rockchip_usb2phy_clk_enable(struct c
55 const struct usb2phy_reg *clkout_ctl;
56 struct regmap *base;
57
58 - rockchip_usb2phy_clkout_ctl(clk, &base, &clkout_ctl);
59 + if (rockchip_usb2phy_clkout_ctl(clk, &base, &clkout_ctl))
60 + return -ENOSYS;
61
62 /* turn on 480m clk output if it is off */
63 if (!property_enabled(base, clkout_ctl)) {
64 @@ -230,7 +238,8 @@ int rockchip_usb2phy_clk_disable(struct
65 const struct usb2phy_reg *clkout_ctl;
66 struct regmap *base;
67
68 - rockchip_usb2phy_clkout_ctl(clk, &base, &clkout_ctl);
69 + if (rockchip_usb2phy_clkout_ctl(clk, &base, &clkout_ctl))
70 + return -ENOSYS;
71
72 /* turn off 480m clk output */
73 property_enable(base, clkout_ctl, false);