usb: xhci: change xhci_resume() parameters to explicit the desired info
Previous signature was:
int xhci_resume(struct xhci_hcd *xhci, pm_message_t msg);
Internally, it extracted two information out of the message:
- whether we are after hibernation: msg.event == PM_EVENT_RESTORE,
- whether this is an auto resume: msg.event == PM_EVENT_AUTO_RESUME.
First bulletpoint is somewhat wrong: driver wants to know if the device
did lose power, it doesn't care about hibernation per se. Knowing that,
refactor to ask upper layers the right questions: (1) "did we lose
power?" and, (2) "is this an auto resume?". Change the signature to:
int xhci_resume(struct xhci_hcd *xhci, bool power_lost,
bool is_auto_resume);
The goal is to allow some upper layers (cdns3-plat) to tell us when
power was lost after system-wise suspend.
Note that lost_power is ORed at the start of xhci_resume() to
xhci->quirks & XHCI_RESET_ON_RESUME || xhci->broken_suspend. It is
simpler to keep those checks inside of xhci_resume() instead of doing
them at each caller of xhci_resume().
Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
Link: https://lore.kernel.org/r/20250205-s2r-cdns-v7-7-13658a271c3c@bootlin.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
9925aa4b02
commit
34cca0ceab
|
|
@ -355,7 +355,7 @@ static int __maybe_unused xhci_histb_resume(struct device *dev)
|
|||
if (!device_may_wakeup(dev))
|
||||
xhci_histb_host_enable(histb);
|
||||
|
||||
return xhci_resume(xhci, PMSG_RESUME);
|
||||
return xhci_resume(xhci, false, false);
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops xhci_histb_pm_ops = {
|
||||
|
|
|
|||
|
|
@ -807,8 +807,10 @@ static int xhci_pci_suspend(struct usb_hcd *hcd, bool do_wakeup)
|
|||
|
||||
static int xhci_pci_resume(struct usb_hcd *hcd, pm_message_t msg)
|
||||
{
|
||||
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
|
||||
struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
|
||||
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
|
||||
struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
|
||||
bool power_lost = msg.event == PM_EVENT_RESTORE;
|
||||
bool is_auto_resume = msg.event == PM_EVENT_AUTO_RESUME;
|
||||
|
||||
reset_control_reset(xhci->reset);
|
||||
|
||||
|
|
@ -839,7 +841,7 @@ static int xhci_pci_resume(struct usb_hcd *hcd, pm_message_t msg)
|
|||
if (xhci->quirks & XHCI_PME_STUCK_QUIRK)
|
||||
xhci_pme_quirk(hcd);
|
||||
|
||||
return xhci_resume(xhci, msg);
|
||||
return xhci_resume(xhci, power_lost, is_auto_resume);
|
||||
}
|
||||
|
||||
static int xhci_pci_poweroff_late(struct usb_hcd *hcd, bool do_wakeup)
|
||||
|
|
|
|||
|
|
@ -479,7 +479,7 @@ static int xhci_plat_suspend(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int xhci_plat_resume_common(struct device *dev, struct pm_message pmsg)
|
||||
static int xhci_plat_resume_common(struct device *dev, bool power_lost)
|
||||
{
|
||||
struct usb_hcd *hcd = dev_get_drvdata(dev);
|
||||
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
|
||||
|
|
@ -501,7 +501,7 @@ static int xhci_plat_resume_common(struct device *dev, struct pm_message pmsg)
|
|||
if (ret)
|
||||
goto disable_clks;
|
||||
|
||||
ret = xhci_resume(xhci, pmsg);
|
||||
ret = xhci_resume(xhci, power_lost, false);
|
||||
if (ret)
|
||||
goto disable_clks;
|
||||
|
||||
|
|
@ -522,12 +522,12 @@ disable_clks:
|
|||
|
||||
static int xhci_plat_resume(struct device *dev)
|
||||
{
|
||||
return xhci_plat_resume_common(dev, PMSG_RESUME);
|
||||
return xhci_plat_resume_common(dev, false);
|
||||
}
|
||||
|
||||
static int xhci_plat_restore(struct device *dev)
|
||||
{
|
||||
return xhci_plat_resume_common(dev, PMSG_RESTORE);
|
||||
return xhci_plat_resume_common(dev, true);
|
||||
}
|
||||
|
||||
static int __maybe_unused xhci_plat_runtime_suspend(struct device *dev)
|
||||
|
|
@ -548,7 +548,7 @@ static int __maybe_unused xhci_plat_runtime_resume(struct device *dev)
|
|||
struct usb_hcd *hcd = dev_get_drvdata(dev);
|
||||
struct xhci_hcd *xhci = hcd_to_xhci(hcd);
|
||||
|
||||
return xhci_resume(xhci, PMSG_AUTO_RESUME);
|
||||
return xhci_resume(xhci, false, true);
|
||||
}
|
||||
|
||||
const struct dev_pm_ops xhci_plat_pm_ops = {
|
||||
|
|
|
|||
|
|
@ -2287,7 +2287,7 @@ static int tegra_xusb_exit_elpg(struct tegra_xusb *tegra, bool is_auto_resume)
|
|||
if (wakeup)
|
||||
tegra_xhci_disable_phy_sleepwalk(tegra);
|
||||
|
||||
err = xhci_resume(xhci, is_auto_resume ? PMSG_AUTO_RESUME : PMSG_RESUME);
|
||||
err = xhci_resume(xhci, false, is_auto_resume);
|
||||
if (err < 0) {
|
||||
dev_err(tegra->dev, "failed to resume XHCI: %d\n", err);
|
||||
goto disable_phy;
|
||||
|
|
|
|||
|
|
@ -994,16 +994,14 @@ EXPORT_SYMBOL_GPL(xhci_suspend);
|
|||
* This is called when the machine transition from S3/S4 mode.
|
||||
*
|
||||
*/
|
||||
int xhci_resume(struct xhci_hcd *xhci, pm_message_t msg)
|
||||
int xhci_resume(struct xhci_hcd *xhci, bool power_lost, bool is_auto_resume)
|
||||
{
|
||||
bool hibernated = (msg.event == PM_EVENT_RESTORE);
|
||||
u32 command, temp = 0;
|
||||
struct usb_hcd *hcd = xhci_to_hcd(xhci);
|
||||
int retval = 0;
|
||||
bool comp_timer_running = false;
|
||||
bool pending_portevent = false;
|
||||
bool suspended_usb3_devs = false;
|
||||
bool reinit_xhc = false;
|
||||
|
||||
if (!hcd->state)
|
||||
return 0;
|
||||
|
|
@ -1022,10 +1020,10 @@ int xhci_resume(struct xhci_hcd *xhci, pm_message_t msg)
|
|||
|
||||
spin_lock_irq(&xhci->lock);
|
||||
|
||||
if (hibernated || xhci->quirks & XHCI_RESET_ON_RESUME || xhci->broken_suspend)
|
||||
reinit_xhc = true;
|
||||
if (xhci->quirks & XHCI_RESET_ON_RESUME || xhci->broken_suspend)
|
||||
power_lost = true;
|
||||
|
||||
if (!reinit_xhc) {
|
||||
if (!power_lost) {
|
||||
/*
|
||||
* Some controllers might lose power during suspend, so wait
|
||||
* for controller not ready bit to clear, just as in xHC init.
|
||||
|
|
@ -1065,12 +1063,12 @@ int xhci_resume(struct xhci_hcd *xhci, pm_message_t msg)
|
|||
/* re-initialize the HC on Restore Error, or Host Controller Error */
|
||||
if ((temp & (STS_SRE | STS_HCE)) &&
|
||||
!(xhci->xhc_state & XHCI_STATE_REMOVING)) {
|
||||
reinit_xhc = true;
|
||||
if (!xhci->broken_suspend)
|
||||
if (!power_lost)
|
||||
xhci_warn(xhci, "xHC error in resume, USBSTS 0x%x, Reinit\n", temp);
|
||||
power_lost = true;
|
||||
}
|
||||
|
||||
if (reinit_xhc) {
|
||||
if (power_lost) {
|
||||
if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) &&
|
||||
!(xhci_all_ports_seen_u0(xhci))) {
|
||||
del_timer_sync(&xhci->comp_mode_recovery_timer);
|
||||
|
|
@ -1168,8 +1166,7 @@ int xhci_resume(struct xhci_hcd *xhci, pm_message_t msg)
|
|||
|
||||
pending_portevent = xhci_pending_portevent(xhci);
|
||||
|
||||
if (suspended_usb3_devs && !pending_portevent &&
|
||||
msg.event == PM_EVENT_AUTO_RESUME) {
|
||||
if (suspended_usb3_devs && !pending_portevent && is_auto_resume) {
|
||||
msleep(120);
|
||||
pending_portevent = xhci_pending_portevent(xhci);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1880,7 +1880,7 @@ int xhci_disable_slot(struct xhci_hcd *xhci, u32 slot_id);
|
|||
int xhci_ext_cap_init(struct xhci_hcd *xhci);
|
||||
|
||||
int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup);
|
||||
int xhci_resume(struct xhci_hcd *xhci, pm_message_t msg);
|
||||
int xhci_resume(struct xhci_hcd *xhci, bool power_lost, bool is_auto_resume);
|
||||
|
||||
irqreturn_t xhci_irq(struct usb_hcd *hcd);
|
||||
irqreturn_t xhci_msi_irq(int irq, void *hcd);
|
||||
|
|
|
|||
Loading…
Reference in New Issue