FAILED: patch "[PATCH] usb: dwc3: fix gadget mode suspend interrupt handler issue" failed to apply to 5.4-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 5.4-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.4.y
git checkout FETCH_HEAD
git cherry-pick -x 4e8ef34e36f2839ef8c8da521ab7035956436818
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2023052257-efficient-hungrily-839b@gregkh' --subject-prefix 'PATCH 5.4.y' HEAD^..
Possible dependencies:
4e8ef34e36f2 ("usb: dwc3: fix gadget mode suspend interrupt handler issue") 92c08a84b53e ("usb: dwc3: Add function suspend and function wakeup support") 047161686b81 ("usb: dwc3: Add remote wakeup handling") 63c4c320ccf7 ("usb: dwc3: gadget: Check for L1/L2/U3 for Start Transfer") 40edb52298df ("usb: dwc3: avoid NULL access of usb_gadget_driver") c560e76319a9 ("usb: dwc3: gadget: Fix START_TRANSFER link state check") 475e8be53d04 ("usb: dwc3: gadget: Check for disabled LPM quirk") f09ddcfcb8c5 ("usb: dwc3: gadget: Prevent EP queuing while stopping transfers") a66a7d48f34a ("Merge 5.11-rc3 into usb-next")
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 4e8ef34e36f2839ef8c8da521ab7035956436818 Mon Sep 17 00:00:00 2001
From: Linyu Yuan <[email protected]>
Date: Fri, 12 May 2023 08:45:24 +0800
Subject: [PATCH] usb: dwc3: fix gadget mode suspend interrupt handler issue
When work in gadget mode, currently driver doesn't update software level link_state correctly as link state change event is not enabled for most devices, in function dwc3_gadget_suspend_interrupt(), it will only pass suspend event to UDC core when software level link state changes, so when interrupt generated in sequences of suspend -> reset -> conndone -> suspend, link state is not updated during reset and conndone, so second suspend interrupt event will not pass to UDC core.
Remove link_state compare in dwc3_gadget_suspend_interrupt() and add a suspended flag to replace the compare function.
drivers/usb/dwc3/core.h +2 -0
@@ -1116,6 +1116,7 @@ struct dwc3_scratchpad_array {* @dis_metastability_quirk: set to disable metastability quirk. * @dis_split_quirk: set to disable split boundary. * @wakeup_configured: set if the device is configured for remote wakeup. +* @suspended: set to track suspend event due to U3/L2. * @imod_interval: set the interrupt moderation interval in 250ns * increments or 0 to disable. * @max_cfg_eps: current max number of IN eps used across all USB configs.
@@ -1332,6 +1333,7 @@ struct dwc3 { unsigned dis_split_quirk:1; unsigned async_callbacks:1; unsigned wakeup_configured:1; + unsigned suspended:1;u16 imod_interval;
drivers/usb/dwc3/gadget.c +11 -1
@@ -2440,6 +2440,7 @@ static int dwc3_gadget_func_wakeup(struct usb_gadget *g, int intf_id)return -EINVAL ; }dwc3_resume_gadget (dwc); + dwc->suspended = false; dwc->link_state =DWC3_LINK_STATE_U0 ; }
@@ -3942,6 +3943,8 @@ static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc) {int reg; + dwc->suspended = false; +dwc3_gadget_set_link_state (dwc,DWC3_LINK_STATE_RX_DET ); reg =dwc3_readl (dwc->regs,DWC3_DCTL );
@@ -3966,6 +3969,8 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc) {u32 reg; + dwc->suspended = false; +/* * Ideally, dwc3_reset_gadget() would trigger the function * drivers to stop any active transfers through ep disable.
@@ -4184,6 +4189,8 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc)static void dwc3_gadget_wakeup_interrupt (struct dwc3 *dwc,unsigned int evtinfo) { + dwc->suspended = false; +/* * TODO take core out of low power mode when that's * implemented.
@@ -4281,6 +4288,7 @@ static void dwc3_gadget_linksts_change_interrupt(struct dwc3 *dwc,if (dwc->gadget->wakeup_armed) {dwc3_gadget_enable_linksts_evts (dwc, false);dwc3_resume_gadget (dwc); + dwc->suspended = false; }break ;case DWC3_LINK_STATE_U1 :
@@ -4307,8 +4315,10 @@ static void dwc3_gadget_suspend_interrupt(struct dwc3 *dwc, {enum dwc3_link_state next = evtinfo &DWC3_LINK_STATE_MASK ; -if (dwc->link_state != next && next ==DWC3_LINK_STATE_U3 ) +if (!dwc->suspended && next ==DWC3_LINK_STATE_U3 ) { + dwc->suspended = true;dwc3_suspend_gadget (dwc); + } dwc->link_state = next; }