Skip to content

Commit 8889b28

Browse files
Tommaso MerciaipH5
authored andcommitted
reset: rzv2h-usb2phy: Keep PHY clock enabled for entire device lifetime
The driver was disabling the USB2 PHY clock immediately after register initialization in probe() and after each reset operation. This left the PHY unclocked even though it must remain active for USB functionality. The behavior appeared to work only when another driver (e.g., USB controller) had already enabled the clock, making operation unreliable and hardware-dependent. In configurations where this driver is the sole clock user, USB functionality would fail. Fix this by: - Enabling the clock once in probe() via pm_runtime_resume_and_get() - Removing all pm_runtime_put() calls from assert/deassert/status - Registering a devm cleanup action to release the clock at removal - Removed rzv2h_usbphy_assert_helper() and its call in rzv2h_usb2phy_reset_probe() This ensures the PHY clock remains enabled for the entire device lifetime, preventing instability and aligning with hardware requirements. Cc: stable@vger.kernel.org Fixes: e3911d7 ("reset: Add USB2PHY port reset driver for Renesas RZ/V2H(P)") Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com> Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
1 parent 223af4a commit 8889b28

1 file changed

Lines changed: 18 additions & 46 deletions

File tree

drivers/reset/reset-rzv2h-usb2phy.c

Lines changed: 18 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,10 @@ static inline struct rzv2h_usb2phy_reset_priv
4949
return container_of(rcdev, struct rzv2h_usb2phy_reset_priv, rcdev);
5050
}
5151

52-
/* This function must be called only after pm_runtime_resume_and_get() has been called */
53-
static void rzv2h_usbphy_assert_helper(struct rzv2h_usb2phy_reset_priv *priv)
52+
static int rzv2h_usbphy_reset_assert(struct reset_controller_dev *rcdev,
53+
unsigned long id)
5454
{
55+
struct rzv2h_usb2phy_reset_priv *priv = rzv2h_usbphy_rcdev_to_priv(rcdev);
5556
const struct rzv2h_usb2phy_reset_of_data *data = priv->data;
5657

5758
scoped_guard(spinlock, &priv->lock) {
@@ -60,24 +61,6 @@ static void rzv2h_usbphy_assert_helper(struct rzv2h_usb2phy_reset_priv *priv)
6061
}
6162

6263
usleep_range(11, 20);
63-
}
64-
65-
static int rzv2h_usbphy_reset_assert(struct reset_controller_dev *rcdev,
66-
unsigned long id)
67-
{
68-
struct rzv2h_usb2phy_reset_priv *priv = rzv2h_usbphy_rcdev_to_priv(rcdev);
69-
struct device *dev = priv->dev;
70-
int ret;
71-
72-
ret = pm_runtime_resume_and_get(dev);
73-
if (ret) {
74-
dev_err(dev, "pm_runtime_resume_and_get failed\n");
75-
return ret;
76-
}
77-
78-
rzv2h_usbphy_assert_helper(priv);
79-
80-
pm_runtime_put(dev);
8164

8265
return 0;
8366
}
@@ -87,44 +70,24 @@ static int rzv2h_usbphy_reset_deassert(struct reset_controller_dev *rcdev,
8770
{
8871
struct rzv2h_usb2phy_reset_priv *priv = rzv2h_usbphy_rcdev_to_priv(rcdev);
8972
const struct rzv2h_usb2phy_reset_of_data *data = priv->data;
90-
struct device *dev = priv->dev;
91-
int ret;
92-
93-
ret = pm_runtime_resume_and_get(dev);
94-
if (ret) {
95-
dev_err(dev, "pm_runtime_resume_and_get failed\n");
96-
return ret;
97-
}
9873

9974
scoped_guard(spinlock, &priv->lock) {
10075
writel(data->reset_deassert_val, priv->base + data->reset_reg);
10176
writel(data->reset2_release_val, priv->base + data->reset2_reg);
10277
writel(data->reset_release_val, priv->base + data->reset_reg);
10378
}
10479

105-
pm_runtime_put(dev);
106-
10780
return 0;
10881
}
10982

11083
static int rzv2h_usbphy_reset_status(struct reset_controller_dev *rcdev,
11184
unsigned long id)
11285
{
11386
struct rzv2h_usb2phy_reset_priv *priv = rzv2h_usbphy_rcdev_to_priv(rcdev);
114-
struct device *dev = priv->dev;
115-
int ret;
11687
u32 reg;
11788

118-
ret = pm_runtime_resume_and_get(dev);
119-
if (ret) {
120-
dev_err(dev, "pm_runtime_resume_and_get failed\n");
121-
return ret;
122-
}
123-
12489
reg = readl(priv->base + priv->data->reset_reg);
12590

126-
pm_runtime_put(dev);
127-
12891
return (reg & priv->data->reset_status_bits) == priv->data->reset_status_bits;
12992
}
13093

@@ -141,6 +104,11 @@ static int rzv2h_usb2phy_reset_of_xlate(struct reset_controller_dev *rcdev,
141104
return 0;
142105
}
143106

107+
static void rzv2h_usb2phy_reset_pm_runtime_put(void *data)
108+
{
109+
pm_runtime_put(data);
110+
}
111+
144112
static int rzv2h_usb2phy_reset_probe(struct platform_device *pdev)
145113
{
146114
const struct rzv2h_usb2phy_reset_of_data *data;
@@ -175,22 +143,26 @@ static int rzv2h_usb2phy_reset_probe(struct platform_device *pdev)
175143
if (error)
176144
return dev_err_probe(dev, error, "pm_runtime_resume_and_get failed\n");
177145

146+
error = devm_add_action_or_reset(dev, rzv2h_usb2phy_reset_pm_runtime_put,
147+
dev);
148+
if (error)
149+
return dev_err_probe(dev, error, "unable to register cleanup action\n");
150+
178151
for (unsigned int i = 0; i < data->init_val_count; i++)
179152
writel(data->init_vals[i].val, priv->base + data->init_vals[i].reg);
180153

181-
/* keep usb2phy in asserted state */
182-
rzv2h_usbphy_assert_helper(priv);
183-
184-
pm_runtime_put(dev);
185-
186154
priv->rcdev.ops = &rzv2h_usbphy_reset_ops;
187155
priv->rcdev.of_reset_n_cells = 0;
188156
priv->rcdev.nr_resets = 1;
189157
priv->rcdev.of_xlate = rzv2h_usb2phy_reset_of_xlate;
190158
priv->rcdev.of_node = dev->of_node;
191159
priv->rcdev.dev = dev;
192160

193-
return devm_reset_controller_register(dev, &priv->rcdev);
161+
error = devm_reset_controller_register(dev, &priv->rcdev);
162+
if (error)
163+
return dev_err_probe(dev, error, "could not register reset controller\n");
164+
165+
return 0;
194166
}
195167

196168
/*

0 commit comments

Comments
 (0)