Message ID | 20231218061420.3460145-2-xu.yang_2@nxp.com |
---|---|
State | Superseded |
Headers | show |
Series | None | expand |
On 23-12-18 14:14:19, Xu Yang wrote: > After the chipidea driver introduce extcon for id and vbus, it's able > to wakeup from another irq source, in case the system with extcon ID > cable, wakeup from usb ID cable and device removal, the usb device > disconnect irq may come firstly before the extcon notifier while system > resume, so we will get 2 "wakeup" irq, one for usb device disconnect; > and one for extcon ID cable change(real wakeup event), current driver > treat them as 2 successive wakeup irq so can't handle it correctly, then > finally the usb irq can't be enabled. This patch adds a check to bypass > further usb events before controller resume finished to fix it. > > Fixes: 1f874edcb731 ("usb: chipidea: add runtime power management support") > cc: <stable@vger.kernel.org> > Signed-off-by: Xu Yang <xu.yang_2@nxp.com> > Signed-off-by: Li Jun <jun.li@nxp.com> Acked-by: Peter Chen <peter.chen@kernel.org> > > --- > Changes in v2: > - no changes > --- > drivers/usb/chipidea/core.c | 7 +++++++ > 1 file changed, 7 insertions(+) > > diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c > index 7ac39a281b8c..85e9c3ab66e9 100644 > --- a/drivers/usb/chipidea/core.c > +++ b/drivers/usb/chipidea/core.c > @@ -523,6 +523,13 @@ static irqreturn_t ci_irq_handler(int irq, void *data) > u32 otgsc = 0; > > if (ci->in_lpm) { > + /* > + * If we already have a wakeup irq pending there, > + * let's just return to wait resume finished firstly. > + */ > + if (ci->wakeup_int) > + return IRQ_HANDLED; > + > disable_irq_nosync(irq); > ci->wakeup_int = true; > pm_runtime_get(ci->dev); > -- > 2.34.1 >
diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c index 7ac39a281b8c..85e9c3ab66e9 100644 --- a/drivers/usb/chipidea/core.c +++ b/drivers/usb/chipidea/core.c @@ -523,6 +523,13 @@ static irqreturn_t ci_irq_handler(int irq, void *data) u32 otgsc = 0; if (ci->in_lpm) { + /* + * If we already have a wakeup irq pending there, + * let's just return to wait resume finished firstly. + */ + if (ci->wakeup_int) + return IRQ_HANDLED; + disable_irq_nosync(irq); ci->wakeup_int = true; pm_runtime_get(ci->dev);