From da325a8c585933a2d791b8cb539053f082c9666a Mon Sep 17 00:00:00 2001 From: Wesley Cheng Date: Wed, 27 Oct 2021 13:10:06 -0700 Subject: [PATCH 1/3] usb: gadget: udc: core: Revise comments for USB ep enable/disable The usb_ep_disable() and usb_ep_enable() routines are being widely used in atomic/interrupt context by function drivers. Hence, the statement about it being able to only run in process context may not be true. Add an explicit comment mentioning that it can be used in atomic context. Change-Id: I509be3e7eba3f61b95c9bbeef6b39f4fb3a55f25 Acked-by: Alan Stern Signed-off-by: Wesley Cheng Link: https://lore.kernel.org/r/1635365407-31337-2-git-send-email-quic_wcheng@quicinc.com Signed-off-by: Greg Kroah-Hartman Git-commit: b0d5d2a71641bb50cada708cc8fdca946a837e9a Git-Repo: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git Signed-off-by: Rohith Kollalsi --- drivers/usb/gadget/udc/core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/udc/core.c b/drivers/usb/gadget/udc/core.c index 1f781d15e53a..826dcefe5760 100644 --- a/drivers/usb/gadget/udc/core.c +++ b/drivers/usb/gadget/udc/core.c @@ -87,7 +87,7 @@ EXPORT_SYMBOL_GPL(usb_ep_set_maxpacket_limit); * configurable, with more generic names like "ep-a". (remember that for * USB, "in" means "towards the USB master".) * - * This routine must be called in process context. + * This routine may be called in an atomic (interrupt) context.. * * returns zero, or a negative error code. */ @@ -132,7 +132,7 @@ EXPORT_SYMBOL_GPL(usb_ep_enable); * gadget drivers must call usb_ep_enable() again before queueing * requests to the endpoint. * - * This routine must be called in process context. + * This routine may be called in an atomic (interrupt) context. * * returns zero, or a negative error code. */ From e326bb5942e2a8d6ecff7ecab44b6343e490c5b8 Mon Sep 17 00:00:00 2001 From: Wesley Cheng Date: Wed, 27 Oct 2021 13:10:07 -0700 Subject: [PATCH 2/3] usb: gadget: f_mass_storage: Disable eps during disconnect When receiving a disconnect event from the UDC, the mass storage function driver currently runs the handle_exception() routine asynchronously. For UDCs that support runtime PM, there is a possibility the UDC is already suspended by the time the do_set_interface() is executed. This can lead to HW register access while the UDC is already suspended. Change-Id: Ie1374cb7c895bd9d5c0129dd18886980dba71712 Acked-by: Alan Stern Signed-off-by: Wesley Cheng Link: https://lore.kernel.org/r/1635365407-31337-3-git-send-email-quic_wcheng@quicinc.com Signed-off-by: Greg Kroah-Hartman Git-commit: 9fff139aeb11186fd8e75860c959c86cb43ab2f6 Git-Repo: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git Signed-off-by: Rohith Kollalsi --- drivers/usb/gadget/function/f_mass_storage.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c index 7c96c4665178..5b59991eb788 100644 --- a/drivers/usb/gadget/function/f_mass_storage.c +++ b/drivers/usb/gadget/function/f_mass_storage.c @@ -2301,6 +2301,16 @@ static void fsg_disable(struct usb_function *f) { struct fsg_dev *fsg = fsg_from_func(f); + /* Disable the endpoints */ + if (fsg->bulk_in_enabled) { + usb_ep_disable(fsg->bulk_in); + fsg->bulk_in_enabled = 0; + } + if (fsg->bulk_out_enabled) { + usb_ep_disable(fsg->bulk_out); + fsg->bulk_out_enabled = 0; + } + __raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE, NULL); } From c86f34751f6717b9c122e7ca25360d7b9c0437ff Mon Sep 17 00:00:00 2001 From: Rohith Kollalsi Date: Tue, 8 Feb 2022 10:33:34 +0530 Subject: [PATCH 3/3] dwc3: gadget: Remove pm_runtime calls from dwc3_gadget_ep_disable There is a chance that ep_disable will be called from mass storage function driver after usb is in LPM as ep_disable in mass storage function driver is called in worker thread context. Hence, Commit 589a7f885ae2 ("usb: dwc3: Don't perform pm rt sync operations in atomic context") added pm_runtime calls for mass storage function driver, so that system can be resumed and then do the ep_disable operations. But Commit e8e83c46c5eb ("usb: gadget: f_mass_storage: Disable eps during disconnect") has changed the implementation of ep_disable in mass storage function driver. It is now being called in atomic context. So there is no chance of ep_disable being called after usb is in lpm. Hence remove the support for pm_runtime calls in ep_disable as they are any how no-op. Change-Id: I5bcc2572da1608b24b1fe1cf14b6f1c3918d2d7a Signed-off-by: Rohith Kollalsi --- drivers/usb/dwc3/gadget.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index bcded2a041c5..0f271d6e080f 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -966,7 +966,6 @@ static int dwc3_gadget_ep_disable(struct usb_ep *ep) struct dwc3 *dwc; unsigned long flags; int ret; - bool call_rpm_put = false; if (!ep) { pr_debug("dwc3: invalid parameters\n"); @@ -981,18 +980,10 @@ static int dwc3_gadget_ep_disable(struct usb_ep *ep) dep->name)) return 0; - if (atomic_read(&dwc->in_lpm)) { - pm_runtime_get_sync(dwc->sysdev); - call_rpm_put = true; - } spin_lock_irqsave(&dwc->lock, flags); ret = __dwc3_gadget_ep_disable(dep); dbg_event(dep->number, "DISABLE", ret); spin_unlock_irqrestore(&dwc->lock, flags); - if (call_rpm_put) { - pm_runtime_mark_last_busy(dwc->sysdev); - pm_runtime_put_autosuspend(dwc->sysdev); - } return ret; }