Hi Greg, Do you think this plan is feasible? Do I need to add more explanations? Thanks, Deng Jie >--- >v2: > * Fix the formatting issues and function naming conventions in the v1 patch. >v1: > * USB: Fix the issue of S4 wakeup queisce phase where task resumption fails > due to USB status. >--- > >diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c >index fb4d18a0b185..7723e7082a36 100644 >--- a/drivers/base/power/main.c >+++ b/drivers/base/power/main.c >@@ -559,6 +559,11 @@ bool dev_pm_may_skip_resume(struct device *dev) > return !dev->power.must_resume && pm_transition.event != PM_EVENT_RESTORE; > } > >+bool pm_event_is_queisce(void) >+{ >+ return pm_transition.event == PM_EVENT_QUIESCE; >+} >+ > static pm_callback_t dpm_subsys_resume_noirq_cb(struct device *dev, > pm_message_t state, > const char **info_p) >diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c >index 77830f120834..af2c60049e4a 100644 >--- a/drivers/usb/core/hcd-pci.c >+++ b/drivers/usb/core/hcd-pci.c >@@ -456,18 +456,25 @@ static int suspend_common(struct device *dev, bool do_wakeup) > /* Optimization: Don't suspend if a root-hub wakeup is > * pending and it would cause the HCD to wake up anyway. > */ >- if (do_wakeup && HCD_WAKEUP_PENDING(hcd)) >- return -EBUSY; >- if (do_wakeup && hcd->shared_hcd && >- HCD_WAKEUP_PENDING(hcd->shared_hcd)) >+ /* Considering the restore process that occurs after >+ * the quiesce phase during S4 wakeup, which essentially >+ * resets all root hubs,checking this wakeup pending status >+ * in USB suspend_common() during the quiesce phase is of >+ * little significance and should therefore be filtered out. >+ */ >+ if (!pm_event_is_queisce() && do_wakeup && >+ (HCD_WAKEUP_PENDING(hcd) || >+ (hcd->shared_hcd && >+ HCD_WAKEUP_PENDING(hcd->shared_hcd)))) > return -EBUSY; > retval = hcd->driver->pci_suspend(hcd, do_wakeup); > suspend_report_result(hcd->driver->pci_suspend, retval); > > /* Check again in case wakeup raced with pci_suspend */ >- if ((retval == 0 && do_wakeup && HCD_WAKEUP_PENDING(hcd)) || >- (retval == 0 && do_wakeup && hcd->shared_hcd && >- HCD_WAKEUP_PENDING(hcd->shared_hcd))) { >+ if (retval == 0 && !pm_event_is_queisce() && do_wakeup && >+ (HCD_WAKEUP_PENDING(hcd) || >+ (hcd->shared_hcd && >+ HCD_WAKEUP_PENDING(hcd->shared_hcd)))) { > if (hcd->driver->pci_resume) > hcd->driver->pci_resume(hcd, false); > retval = -EBUSY; >diff --git a/include/linux/pm.h b/include/linux/pm.h >index 4c441be03079..dad87c9ecfee 100644 >--- a/include/linux/pm.h >+++ b/include/linux/pm.h >@@ -758,6 +758,7 @@ extern void pm_generic_complete(struct device *dev); > > extern bool dev_pm_may_skip_resume(struct device *dev); > extern bool dev_pm_smart_suspend_and_suspended(struct device *dev); >+extern bool pm_event_is_queisce(void); > > #else /* !CONFIG_PM_SLEEP */ >