Re: [PATCH v2] USB: Fix the issue of S4 wakeup queisce phase where task resumption fails due to USB status

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 */
>




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux