From: Macpaul Lin macpaul.lin@mediatek.com
stable inclusion from stable-v5.10.114 commit 8ba02cebb734cb4dd832e565770de10c924fec0e category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I5IY1V
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
commit 456244aeecd54249096362a173dfe06b82a5cafa upstream.
Issue description: When an OTG port has been switched to device role and then switch back to host role again, the USB 3.0 Host (XHCI) will not be able to detect "plug in event of a connected USB 2.0/1.0 ((Highspeed and Fullspeed) devices until system reboot.
Root cause and Solution: There is a condition checking flag "ssusb->otg_switch.is_u3_drd" in toggle_opstate(). At the end of role switch procedure, toggle_opstate() will be called to set DC_SESSION and SOFT_CONN bit. If "is_u3_drd" was set and switched the role to USB host 3.0, bit DC_SESSION and SOFT_CONN will be skipped hence caused the port cannot detect connected USB 2.0 (Highspeed and Fullspeed) devices. Simply remove the condition check to solve this issue.
Fixes: d0ed062a8b75 ("usb: mtu3: dual-role mode support") Cc: stable@vger.kernel.org Tested-by: Fabien Parent fparent@baylibre.com Reviewed-by: Chunfeng Yun chunfeng.yun@mediatek.com Signed-off-by: Macpaul Lin macpaul.lin@mediatek.com Signed-off-by: Tainping Fang tianping.fang@mediatek.com Link: https://lore.kernel.org/r/20220419081245.21015-1-macpaul.lin@mediatek.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com --- drivers/usb/mtu3/mtu3_dr.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/mtu3/mtu3_dr.c b/drivers/usb/mtu3/mtu3_dr.c index 04f666e85731..16731324e5d8 100644 --- a/drivers/usb/mtu3/mtu3_dr.c +++ b/drivers/usb/mtu3/mtu3_dr.c @@ -41,10 +41,8 @@ static char *mailbox_state_string(enum mtu3_vbus_id_state state)
static void toggle_opstate(struct ssusb_mtk *ssusb) { - if (!ssusb->otg_switch.is_u3_drd) { - mtu3_setbits(ssusb->mac_base, U3D_DEVICE_CONTROL, DC_SESSION); - mtu3_setbits(ssusb->mac_base, U3D_POWER_MANAGEMENT, SOFT_CONN); - } + mtu3_setbits(ssusb->mac_base, U3D_DEVICE_CONTROL, DC_SESSION); + mtu3_setbits(ssusb->mac_base, U3D_POWER_MANAGEMENT, SOFT_CONN); }
/* only port0 supports dual-role mode */