FAILED: patch "[PATCH] phy: renesas: rcar-gen3-usb2: Fix role detection on" failed to apply to 5.15-stable tree
Subsystems (4)
[email protected]
maintainerThe patch below does not apply to the 5.15-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.15.y
git checkout FETCH_HEAD
git cherry-pick -x 54c4c58713aaff76c2422ff5750e557ab3b100d7
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2025051923-veto-uncivil-bb49@gregkh' --subject-prefix 'PATCH 5.15.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 54c4c58713aaff76c2422ff5750e557ab3b100d7 Mon Sep 17 00:00:00 2001
From: Claudiu Beznea <[email protected]>
Date: Wed, 7 May 2025 15:50:28 +0300
Subject: [PATCH] phy: renesas: rcar-gen3-usb2: Fix role detection on
unbind/bind
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.
drivers/phy/renesas/phy-rcar-gen3-usb2.c +14 -19
@@ -107,7 +107,6 @@ struct rcar_gen3_phy {struct rcar_gen3_chan *ch;u32 int_enable_bits;bool initialized; -bool otg_initialized;bool powered; };
@@ -320,16 +319,15 @@ 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; - -for (i =0 ; i <NUM_OF_PHYS ; i++) { -if (ch->rphys[i].otg_initialized) -return false; +for (enum rcar_gen3_phy_index 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)
@@ -351,7 +349,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" ))
@@ -389,7 +387,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" :
@@ -402,6 +400,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 |
@@ -465,12 +466,9 @@ static int rcar_gen3_phy_usb2_init(struct phy *p)writel (USB2_SPD_RSM_TIMSET_INIT , usb2_base +USB2_SPD_RSM_TIMSET );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;
@@ -486,9 +484,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))