* [PATCH 5.10.y 0/4] phy: renesas: rcar-gen3-usb2: Fixes for Renesas GEN3 USB2 PHY
@ 2026-04-07 11:37 Claudiu
2026-04-07 11:37 ` [PATCH 5.10.y 1/4] phy: renesas: rcar-gen3-usb2: Fix role detection on unbind/bind Claudiu
` (4 more replies)
0 siblings, 5 replies; 6+ messages in thread
From: Claudiu @ 2026-04-07 11:37 UTC (permalink / raw)
To: stable; +Cc: claudiu.beznea
From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Hi,
Series backports fixes to the Renesas RCAR GEN3 USB2 PHY driver. Fixes
are already backported to the other stable trees.
Thank you,
Claudiu
Claudiu Beznea (4):
phy: renesas: rcar-gen3-usb2: Fix role detection on unbind/bind
phy: renesas: rcar-gen3-usb2: Move IRQ request in probe
phy: renesas: rcar-gen3-usb2: Lock around hardware registers and
driver data
phy: renesas: rcar-gen3-usb2: Assert PLL reset on PHY power off
drivers/phy/renesas/phy-rcar-gen3-usb2.c | 122 +++++++++++++----------
1 file changed, 71 insertions(+), 51 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 5.10.y 1/4] phy: renesas: rcar-gen3-usb2: Fix role detection on unbind/bind
2026-04-07 11:37 [PATCH 5.10.y 0/4] phy: renesas: rcar-gen3-usb2: Fixes for Renesas GEN3 USB2 PHY Claudiu
@ 2026-04-07 11:37 ` Claudiu
2026-04-07 11:37 ` [PATCH 5.10.y 2/4] phy: renesas: rcar-gen3-usb2: Move IRQ request in probe Claudiu
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Claudiu @ 2026-04-07 11:37 UTC (permalink / raw)
To: stable; +Cc: claudiu.beznea
From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
commit 54c4c58713aaff76c2422ff5750e557ab3b100d7 upstream.
It has been observed on the Renesas RZ/G3S SoC that unbinding and binding
the PHY driver leads to role autodetection failures. This issue occurs when
PHY 3 is the first initialized PHY. PHY 3 does not have an interrupt
associated with the USB2_INT_ENABLE register (as
rcar_gen3_int_enable[3] = 0). As a result, rcar_gen3_init_otg() is called
to initialize OTG without enabling PHY interrupts.
To resolve this, add rcar_gen3_is_any_otg_rphy_initialized() and call it in
role_store(), role_show(), and rcar_gen3_init_otg(). At the same time,
rcar_gen3_init_otg() is only called when initialization for a PHY with
interrupt bits is in progress. As a result, the
struct rcar_gen3_phy::otg_initialized is no longer needed.
Fixes: 549b6b55b005 ("phy: renesas: rcar-gen3-usb2: enable/disable independent irqs")
Cc: stable@vger.kernel.org
Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Tested-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Link: https://lore.kernel.org/r/20250507125032.565017-2-claudiu.beznea.uj@bp.renesas.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
[claudiu.beznea: declare the i iterrator from
rcar_gen3_is_any_otg_rphy_initialized() outside of for loop]
Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
---
drivers/phy/renesas/phy-rcar-gen3-usb2.c | 32 +++++++++++-------------
1 file changed, 14 insertions(+), 18 deletions(-)
diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index ea01a121b8fc..646a5140b30e 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -98,7 +98,6 @@ struct rcar_gen3_phy {
struct rcar_gen3_chan *ch;
u32 int_enable_bits;
bool initialized;
- bool otg_initialized;
bool powered;
};
@@ -288,16 +287,16 @@ static bool rcar_gen3_is_any_rphy_initialized(struct rcar_gen3_chan *ch)
return false;
}
-static bool rcar_gen3_needs_init_otg(struct rcar_gen3_chan *ch)
+static bool rcar_gen3_is_any_otg_rphy_initialized(struct rcar_gen3_chan *ch)
{
- int i;
+ enum rcar_gen3_phy_index i;
- for (i = 0; i < NUM_OF_PHYS; i++) {
- if (ch->rphys[i].otg_initialized)
- return false;
+ for (i = PHY_INDEX_BOTH_HC; i <= PHY_INDEX_EHCI; i++) {
+ if (ch->rphys[i].initialized)
+ return true;
}
- return true;
+ return false;
}
static bool rcar_gen3_are_all_rphys_power_off(struct rcar_gen3_chan *ch)
@@ -319,7 +318,7 @@ static ssize_t role_store(struct device *dev, struct device_attribute *attr,
bool is_b_device;
enum phy_mode cur_mode, new_mode;
- if (!ch->is_otg_channel || !rcar_gen3_is_any_rphy_initialized(ch))
+ if (!ch->is_otg_channel || !rcar_gen3_is_any_otg_rphy_initialized(ch))
return -EIO;
if (sysfs_streq(buf, "host"))
@@ -357,7 +356,7 @@ static ssize_t role_show(struct device *dev, struct device_attribute *attr,
{
struct rcar_gen3_chan *ch = dev_get_drvdata(dev);
- if (!ch->is_otg_channel || !rcar_gen3_is_any_rphy_initialized(ch))
+ if (!ch->is_otg_channel || !rcar_gen3_is_any_otg_rphy_initialized(ch))
return -EIO;
return sprintf(buf, "%s\n", rcar_gen3_is_host(ch) ? "host" :
@@ -370,6 +369,9 @@ static void rcar_gen3_init_otg(struct rcar_gen3_chan *ch)
void __iomem *usb2_base = ch->base;
u32 val;
+ if (!ch->is_otg_channel || rcar_gen3_is_any_otg_rphy_initialized(ch))
+ return;
+
/* Should not use functions of read-modify-write a register */
val = readl(usb2_base + USB2_LINECTRL1);
val = (val & ~USB2_LINECTRL1_DP_RPD) | USB2_LINECTRL1_DPRPD_EN |
@@ -435,12 +437,9 @@ static int rcar_gen3_phy_usb2_init(struct phy *p)
writel(USB2_OC_TIMSET_INIT, usb2_base + USB2_OC_TIMSET);
}
- /* Initialize otg part */
- if (channel->is_otg_channel) {
- if (rcar_gen3_needs_init_otg(channel))
- rcar_gen3_init_otg(channel);
- rphy->otg_initialized = true;
- }
+ /* Initialize otg part (only if we initialize a PHY with IRQs). */
+ if (rphy->int_enable_bits)
+ rcar_gen3_init_otg(channel);
rphy->initialized = true;
@@ -456,9 +455,6 @@ static int rcar_gen3_phy_usb2_exit(struct phy *p)
rphy->initialized = false;
- if (channel->is_otg_channel)
- rphy->otg_initialized = false;
-
val = readl(usb2_base + USB2_INT_ENABLE);
val &= ~rphy->int_enable_bits;
if (!rcar_gen3_is_any_rphy_initialized(channel))
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 5.10.y 2/4] phy: renesas: rcar-gen3-usb2: Move IRQ request in probe
2026-04-07 11:37 [PATCH 5.10.y 0/4] phy: renesas: rcar-gen3-usb2: Fixes for Renesas GEN3 USB2 PHY Claudiu
2026-04-07 11:37 ` [PATCH 5.10.y 1/4] phy: renesas: rcar-gen3-usb2: Fix role detection on unbind/bind Claudiu
@ 2026-04-07 11:37 ` Claudiu
2026-04-07 11:37 ` [PATCH 5.10.y 3/4] phy: renesas: rcar-gen3-usb2: Lock around hardware registers and driver data Claudiu
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Claudiu @ 2026-04-07 11:37 UTC (permalink / raw)
To: stable; +Cc: claudiu.beznea
From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
commit de76809f60cc938d3580bbbd5b04b7d12af6ce3a upstream.
Commit 08b0ad375ca6 ("phy: renesas: rcar-gen3-usb2: move IRQ registration
to init") moved the IRQ request operation from probe to
struct phy_ops::phy_init API to avoid triggering interrupts (which lead to
register accesses) while the PHY clocks (enabled through runtime PM APIs)
are not active. If this happens, it results in a synchronous abort.
One way to reproduce this issue is by enabling CONFIG_DEBUG_SHIRQ, which
calls free_irq() on driver removal.
Move the IRQ request and free operations back to probe, and take the
runtime PM state into account in IRQ handler. This commit is preparatory
for the subsequent fixes in this series.
Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Tested-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Link: https://lore.kernel.org/r/20250507125032.565017-3-claudiu.beznea.uj@bp.renesas.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
[claudiu.beznea: fixed conflicts by:
- dropping irq and obint_enable_bits members of rcar_gen3_chan
- using USB2_OBINT_BITS marco in rcar_gen3_phy_usb2_irq()
- keeping irq local variable in rcar_gen3_phy_usb2_probe()
- dropping channel->irq and channel->obint_enable_bits asssignement from
probe
- keeping platform_set_drvdata() and channel->dev assignment in probe]
Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
---
drivers/phy/renesas/phy-rcar-gen3-usb2.c | 46 +++++++++++++-----------
1 file changed, 26 insertions(+), 20 deletions(-)
diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index 646a5140b30e..f66e0daa2364 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -110,7 +110,6 @@ struct rcar_gen3_chan {
struct work_struct work;
struct mutex lock; /* protects rphys[...].powered */
enum usb_dr_mode dr_mode;
- int irq;
bool extcon_host;
bool is_otg_channel;
bool uses_otg_pins;
@@ -396,16 +395,25 @@ static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch)
{
struct rcar_gen3_chan *ch = _ch;
void __iomem *usb2_base = ch->base;
- u32 status = readl(usb2_base + USB2_OBINTSTA);
+ struct device *dev = ch->dev;
irqreturn_t ret = IRQ_NONE;
+ u32 status;
+ pm_runtime_get_noresume(dev);
+
+ if (pm_runtime_suspended(dev))
+ goto rpm_put;
+
+ status = readl(usb2_base + USB2_OBINTSTA);
if (status & USB2_OBINT_BITS) {
- dev_vdbg(ch->dev, "%s: %08x\n", __func__, status);
+ dev_vdbg(dev, "%s: %08x\n", __func__, status);
writel(USB2_OBINT_BITS, usb2_base + USB2_OBINTSTA);
rcar_gen3_device_recognition(ch);
ret = IRQ_HANDLED;
}
+rpm_put:
+ pm_runtime_put_noidle(dev);
return ret;
}
@@ -415,17 +423,6 @@ static int rcar_gen3_phy_usb2_init(struct phy *p)
struct rcar_gen3_chan *channel = rphy->ch;
void __iomem *usb2_base = channel->base;
u32 val;
- int ret;
-
- if (!rcar_gen3_is_any_rphy_initialized(channel) && channel->irq >= 0) {
- INIT_WORK(&channel->work, rcar_gen3_phy_usb2_work);
- ret = request_irq(channel->irq, rcar_gen3_phy_usb2_irq,
- IRQF_SHARED, dev_name(channel->dev), channel);
- if (ret < 0) {
- dev_err(channel->dev, "No irq handler (%d)\n", channel->irq);
- return ret;
- }
- }
/* Initialize USB2 part */
val = readl(usb2_base + USB2_INT_ENABLE);
@@ -461,9 +458,6 @@ static int rcar_gen3_phy_usb2_exit(struct phy *p)
val &= ~USB2_INT_ENABLE_UCOM_INTEN;
writel(val, usb2_base + USB2_INT_ENABLE);
- if (channel->irq >= 0 && !rcar_gen3_is_any_rphy_initialized(channel))
- free_irq(channel->irq, channel);
-
return 0;
}
@@ -612,7 +606,7 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
struct phy_provider *provider;
struct resource *res;
const struct phy_ops *phy_usb2_ops;
- int ret = 0, i;
+ int ret = 0, i, irq;
if (!dev->of_node) {
dev_err(dev, "This driver needs device tree\n");
@@ -628,8 +622,6 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
if (IS_ERR(channel->base))
return PTR_ERR(channel->base);
- /* get irq number here and request_irq for OTG in phy_init */
- channel->irq = platform_get_irq_optional(pdev, 0);
channel->dr_mode = rcar_gen3_get_dr_mode(dev->of_node);
if (channel->dr_mode != USB_DR_MODE_UNKNOWN) {
channel->is_otg_channel = true;
@@ -683,6 +675,20 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, channel);
channel->dev = dev;
+
+ irq = platform_get_irq_optional(pdev, 0);
+ if (irq < 0 && irq != -ENXIO) {
+ ret = irq;
+ goto error;
+ } else if (irq > 0) {
+ INIT_WORK(&channel->work, rcar_gen3_phy_usb2_work);
+ ret = devm_request_irq(dev, irq, rcar_gen3_phy_usb2_irq,
+ IRQF_SHARED, dev_name(dev), channel);
+ if (ret < 0) {
+ dev_err(dev, "Failed to request irq (%d)\n", irq);
+ goto error;
+ }
+ }
provider = devm_of_phy_provider_register(dev, rcar_gen3_phy_usb2_xlate);
if (IS_ERR(provider)) {
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 5.10.y 3/4] phy: renesas: rcar-gen3-usb2: Lock around hardware registers and driver data
2026-04-07 11:37 [PATCH 5.10.y 0/4] phy: renesas: rcar-gen3-usb2: Fixes for Renesas GEN3 USB2 PHY Claudiu
2026-04-07 11:37 ` [PATCH 5.10.y 1/4] phy: renesas: rcar-gen3-usb2: Fix role detection on unbind/bind Claudiu
2026-04-07 11:37 ` [PATCH 5.10.y 2/4] phy: renesas: rcar-gen3-usb2: Move IRQ request in probe Claudiu
@ 2026-04-07 11:37 ` Claudiu
2026-04-07 11:37 ` [PATCH 5.10.y 4/4] phy: renesas: rcar-gen3-usb2: Assert PLL reset on PHY power off Claudiu
2026-04-08 1:02 ` [PATCH 5.10.y 0/4] phy: renesas: rcar-gen3-usb2: Fixes for Renesas GEN3 USB2 PHY Sasha Levin
4 siblings, 0 replies; 6+ messages in thread
From: Claudiu @ 2026-04-07 11:37 UTC (permalink / raw)
To: stable; +Cc: claudiu.beznea
From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
commit 55a387ebb9219cbe4edfa8ba9996ccb0e7ad4932 upstream.
The phy-rcar-gen3-usb2 driver exposes four individual PHYs that are
requested and configured by PHY users. The struct phy_ops APIs access the
same set of registers to configure all PHYs. Additionally, PHY settings can
be modified through sysfs or an IRQ handler. While some struct phy_ops APIs
are protected by a driver-wide mutex, others rely on individual
PHY-specific mutexes.
This approach can lead to various issues, including:
1/ the IRQ handler may interrupt PHY settings in progress, racing with
hardware configuration protected by a mutex lock
2/ due to msleep(20) in rcar_gen3_init_otg(), while a configuration thread
suspends to wait for the delay, another thread may try to configure
another PHY (with phy_init() + phy_power_on()); re-running the
phy_init() goes to the exact same configuration code, re-running the
same hardware configuration on the same set of registers (and bits)
which might impact the result of the msleep for the 1st configuring
thread
3/ sysfs can configure the hardware (though role_store()) and it can
still race with the phy_init()/phy_power_on() APIs calling into the
drivers struct phy_ops
To address these issues, add a spinlock to protect hardware register access
and driver private data structures (e.g., calls to
rcar_gen3_is_any_rphy_initialized()). Checking driver-specific data remains
necessary as all PHY instances share common settings. With this change,
the existing mutex protection is removed and the cleanup.h helpers are
used.
While at it, to keep the code simpler, do not skip
regulator_enable()/regulator_disable() APIs in
rcar_gen3_phy_usb2_power_on()/rcar_gen3_phy_usb2_power_off() as the
regulators enable/disable operations are reference counted anyway.
Fixes: f3b5a8d9b50d ("phy: rcar-gen3-usb2: Add R-Car Gen3 USB2 PHY driver")
Cc: stable@vger.kernel.org
Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Tested-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Link: https://lore.kernel.org/r/20250507125032.565017-4-claudiu.beznea.uj@bp.renesas.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
[claudiu.beznea:
- in rcar_gen3_init_otg(): fixed conflict by droppping ch->soc_no_adp_ctrl check
- in rcar_gen3_phy_usb2_irq() use spin_lock()/spin_unlock() as scoped_guard()
is not avaialable in v5.10
- in probe(): replace mutex_init() with spin_lock_init()
- rcar_gen3_phy_usb2_power_off() replaced scoped_guard() as it is not
available in v5.10
- in rcar_gen3_phy_usb2_power_on() droppped guard to avoid compilation
warning "ISO C90 forbids mixed declarations and code"]
Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
---
drivers/phy/renesas/phy-rcar-gen3-usb2.c | 41 +++++++++++++++---------
1 file changed, 26 insertions(+), 15 deletions(-)
diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index f66e0daa2364..558c07512c05 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -9,6 +9,7 @@
* Copyright (C) 2014 Cogent Embedded, Inc.
*/
+#include <linux/cleanup.h>
#include <linux/extcon-provider.h>
#include <linux/interrupt.h>
#include <linux/io.h>
@@ -108,7 +109,7 @@ struct rcar_gen3_chan {
struct rcar_gen3_phy rphys[NUM_OF_PHYS];
struct regulator *vbus;
struct work_struct work;
- struct mutex lock; /* protects rphys[...].powered */
+ spinlock_t lock; /* protects access to hardware and driver data structure. */
enum usb_dr_mode dr_mode;
bool extcon_host;
bool is_otg_channel;
@@ -317,6 +318,8 @@ static ssize_t role_store(struct device *dev, struct device_attribute *attr,
bool is_b_device;
enum phy_mode cur_mode, new_mode;
+ guard(spinlock_irqsave)(&ch->lock);
+
if (!ch->is_otg_channel || !rcar_gen3_is_any_otg_rphy_initialized(ch))
return -EIO;
@@ -404,6 +407,8 @@ static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch)
if (pm_runtime_suspended(dev))
goto rpm_put;
+ spin_lock(&ch->lock);
+
status = readl(usb2_base + USB2_OBINTSTA);
if (status & USB2_OBINT_BITS) {
dev_vdbg(dev, "%s: %08x\n", __func__, status);
@@ -412,6 +417,8 @@ static irqreturn_t rcar_gen3_phy_usb2_irq(int irq, void *_ch)
ret = IRQ_HANDLED;
}
+ spin_unlock(&ch->lock);
+
rpm_put:
pm_runtime_put_noidle(dev);
return ret;
@@ -424,6 +431,8 @@ static int rcar_gen3_phy_usb2_init(struct phy *p)
void __iomem *usb2_base = channel->base;
u32 val;
+ guard(spinlock_irqsave)(&channel->lock);
+
/* Initialize USB2 part */
val = readl(usb2_base + USB2_INT_ENABLE);
val |= USB2_INT_ENABLE_UCOM_INTEN | rphy->int_enable_bits;
@@ -450,6 +459,8 @@ static int rcar_gen3_phy_usb2_exit(struct phy *p)
void __iomem *usb2_base = channel->base;
u32 val;
+ guard(spinlock_irqsave)(&channel->lock);
+
rphy->initialized = false;
val = readl(usb2_base + USB2_INT_ENABLE);
@@ -466,19 +477,21 @@ static int rcar_gen3_phy_usb2_power_on(struct phy *p)
struct rcar_gen3_phy *rphy = phy_get_drvdata(p);
struct rcar_gen3_chan *channel = rphy->ch;
void __iomem *usb2_base = channel->base;
+ unsigned long flags;
u32 val;
int ret = 0;
- mutex_lock(&channel->lock);
- if (!rcar_gen3_are_all_rphys_power_off(channel))
- goto out;
-
if (channel->vbus) {
ret = regulator_enable(channel->vbus);
if (ret)
- goto out;
+ return ret;
}
+ spin_lock_irqsave(&channel->lock, flags);
+
+ if (!rcar_gen3_are_all_rphys_power_off(channel))
+ goto out;
+
val = readl(usb2_base + USB2_USBCTR);
val |= USB2_USBCTR_PLL_RST;
writel(val, usb2_base + USB2_USBCTR);
@@ -488,7 +501,8 @@ static int rcar_gen3_phy_usb2_power_on(struct phy *p)
out:
/* The powered flag should be set for any other phys anyway */
rphy->powered = true;
- mutex_unlock(&channel->lock);
+
+ spin_unlock_irqrestore(&channel->lock, flags);
return 0;
}
@@ -497,20 +511,16 @@ static int rcar_gen3_phy_usb2_power_off(struct phy *p)
{
struct rcar_gen3_phy *rphy = phy_get_drvdata(p);
struct rcar_gen3_chan *channel = rphy->ch;
+ unsigned long flags;
int ret = 0;
- mutex_lock(&channel->lock);
+ spin_lock_irqsave(&channel->lock, flags);
rphy->powered = false;
-
- if (!rcar_gen3_are_all_rphys_power_off(channel))
- goto out;
+ spin_unlock_irqrestore(&channel->lock, flags);
if (channel->vbus)
ret = regulator_disable(channel->vbus);
-out:
- mutex_unlock(&channel->lock);
-
return ret;
}
@@ -650,7 +660,8 @@ static int rcar_gen3_phy_usb2_probe(struct platform_device *pdev)
goto error;
}
- mutex_init(&channel->lock);
+ spin_lock_init(&channel->lock);
+
for (i = 0; i < NUM_OF_PHYS; i++) {
channel->rphys[i].phy = devm_phy_create(dev, NULL,
phy_usb2_ops);
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 5.10.y 4/4] phy: renesas: rcar-gen3-usb2: Assert PLL reset on PHY power off
2026-04-07 11:37 [PATCH 5.10.y 0/4] phy: renesas: rcar-gen3-usb2: Fixes for Renesas GEN3 USB2 PHY Claudiu
` (2 preceding siblings ...)
2026-04-07 11:37 ` [PATCH 5.10.y 3/4] phy: renesas: rcar-gen3-usb2: Lock around hardware registers and driver data Claudiu
@ 2026-04-07 11:37 ` Claudiu
2026-04-08 1:02 ` [PATCH 5.10.y 0/4] phy: renesas: rcar-gen3-usb2: Fixes for Renesas GEN3 USB2 PHY Sasha Levin
4 siblings, 0 replies; 6+ messages in thread
From: Claudiu @ 2026-04-07 11:37 UTC (permalink / raw)
To: stable; +Cc: claudiu.beznea
From: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
commit 9ce71e85b29eb63e48e294479742e670513f03a0 upstream.
Assert PLL reset on PHY power off. This saves power.
Fixes: f3b5a8d9b50d ("phy: rcar-gen3-usb2: Add R-Car Gen3 USB2 PHY driver")
Cc: stable@vger.kernel.org
Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Tested-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
Link: https://lore.kernel.org/r/20250507125032.565017-5-claudiu.beznea.uj@bp.renesas.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
[claudiu.beznea: fixed conflict in rcar_gen3_phy_usb2_power_off() by
using spin_lock_irqsave()/spin_unlock_irqrestore() instead of
scoped_guard()]
Signed-off-by: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com>
---
drivers/phy/renesas/phy-rcar-gen3-usb2.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
index 558c07512c05..9fcbde094699 100644
--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c
+++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c
@@ -516,8 +516,15 @@ static int rcar_gen3_phy_usb2_power_off(struct phy *p)
spin_lock_irqsave(&channel->lock, flags);
rphy->powered = false;
- spin_unlock_irqrestore(&channel->lock, flags);
+ if (rcar_gen3_are_all_rphys_power_off(channel)) {
+ u32 val = readl(channel->base + USB2_USBCTR);
+
+ val |= USB2_USBCTR_PLL_RST;
+ writel(val, channel->base + USB2_USBCTR);
+ }
+ spin_unlock_irqrestore(&channel->lock, flags);
+
if (channel->vbus)
ret = regulator_disable(channel->vbus);
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 5.10.y 0/4] phy: renesas: rcar-gen3-usb2: Fixes for Renesas GEN3 USB2 PHY
2026-04-07 11:37 [PATCH 5.10.y 0/4] phy: renesas: rcar-gen3-usb2: Fixes for Renesas GEN3 USB2 PHY Claudiu
` (3 preceding siblings ...)
2026-04-07 11:37 ` [PATCH 5.10.y 4/4] phy: renesas: rcar-gen3-usb2: Assert PLL reset on PHY power off Claudiu
@ 2026-04-08 1:02 ` Sasha Levin
4 siblings, 0 replies; 6+ messages in thread
From: Sasha Levin @ 2026-04-08 1:02 UTC (permalink / raw)
To: Claudiu Beznea; +Cc: stable
On Tue, Apr 07, 2026 at 02:37:38PM +0300, Claudiu wrote:
> Series backports fixes to the Renesas RCAR GEN3 USB2 PHY driver. Fixes
> are already backported to the other stable trees.
Queued for 5.10 and 5.15, thanks.
-- Sasha
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-04-08 1:02 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-07 11:37 [PATCH 5.10.y 0/4] phy: renesas: rcar-gen3-usb2: Fixes for Renesas GEN3 USB2 PHY Claudiu
2026-04-07 11:37 ` [PATCH 5.10.y 1/4] phy: renesas: rcar-gen3-usb2: Fix role detection on unbind/bind Claudiu
2026-04-07 11:37 ` [PATCH 5.10.y 2/4] phy: renesas: rcar-gen3-usb2: Move IRQ request in probe Claudiu
2026-04-07 11:37 ` [PATCH 5.10.y 3/4] phy: renesas: rcar-gen3-usb2: Lock around hardware registers and driver data Claudiu
2026-04-07 11:37 ` [PATCH 5.10.y 4/4] phy: renesas: rcar-gen3-usb2: Assert PLL reset on PHY power off Claudiu
2026-04-08 1:02 ` [PATCH 5.10.y 0/4] phy: renesas: rcar-gen3-usb2: Fixes for Renesas GEN3 USB2 PHY Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox