[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20240926082036.312203-1-dengjie03@kylinos.cn>
Date: Thu, 26 Sep 2024 16:20:36 +0800
From: Deng Jie <dengjie03@...inos.cn>
To: gregkh@...uxfoundation.org
Cc: rafael@...nel.org,
pavel@....cz,
len.brown@...el.com,
linux-usb@...r.kernel.org,
linux-kernel@...r.kernel.org,
linux-pm@...r.kernel.org,
xiehongyu1@...inos.cn,
duanchenghao@...inos.cn,
xiongxin@...inos.cn
Subject: Re: [PATCH v2] USB: Fix the issue of S4 wakeup queisce phase where task resumption fails due to USB status
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 */
>
Powered by blists - more mailing lists