[opensuse-kernel] [PATCH] xhci: Fix spurious wakeups after S5 on Haswell
Hey, here is a patch/fix for openSuse 13.1 that will fix the following issue: Haswell LynxPoint and LynxPoint-LP with the recent Intel BIOS show mysterious wakeups after shutdown occasionally. After discussing with BIOS engineers, they explained that the new BIOS expects that the wakeup sources are cleared and set to D3 for all wakeup devices when the system is going to sleep or power off, but the current xhci driver doesn't do this properly (partly intentionally). This patch introduces a new quirk, XHCI_HSW_SPURIOUS_WAKEUP, for fixing the spurious wakeups at S5 by calling xhci_stop() instead of its stripped version in the xhci shutdown ops, and setting the device to PCI D3 at shutdown and remove ops. Ciao, -- Rick Salevsky, Trainee SUSE LINUX GmbH, Maxfeldstr. 5, D-90409 Nuernberg Tel: +49-911-74053-538 - rsalevsky@suse.com SUSE LINUX GmbH, GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer, HRB 21284 (AG Nürnberg)
At Thu, 28 Nov 2013 14:51:20 +0100, Rick Salevsky wrote:
[1 <text/plain; UTF-8 (8bit)>] Hey, here is a patch/fix for openSuse 13.1 that will fix the following issue:
Haswell LynxPoint and LynxPoint-LP with the recent Intel BIOS show mysterious wakeups after shutdown occasionally. After discussing with BIOS engineers, they explained that the new BIOS expects that the wakeup sources are cleared and set to D3 for all wakeup devices when the system is going to sleep or power off, but the current xhci driver doesn't do this properly (partly intentionally).
This patch introduces a new quirk, XHCI_HSW_SPURIOUS_WAKEUP, for fixing the spurious wakeups at S5 by calling xhci_stop() instead of its stripped version in the xhci shutdown ops, and setting the device to PCI D3 at shutdown and remove ops.
Could you add required tags like References and Git-commit, and resubmit? thanks, Takashi
Ciao, -- Rick Salevsky, Trainee SUSE LINUX GmbH, Maxfeldstr. 5, D-90409 Nuernberg Tel: +49-911-74053-538 - rsalevsky@suse.com SUSE LINUX GmbH, GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer, HRB 21284 (AG Nürnberg) [2 xhci-Fix-spurious-wakeups-after-S5-on-Haswell.patch <text/x-patch; UTF-8 (7bit)>]
From fa10dee546b60b6281468db375816451618c2194 Mon Sep 17 00:00:00 2001 From: Takashi Iwai <tiwai@suse.de> Date: Thu, 12 Sep 2013 08:11:06 +0200 Subject: [PATCH] xhci: Fix spurious wakeups after S5 on Haswell
commit 638298dc66ea36623dbc2757a24fc2c4ab41b016 upstream.
Haswell LynxPoint and LynxPoint-LP with the recent Intel BIOS show mysterious wakeups after shutdown occasionally. After discussing with BIOS engineers, they explained that the new BIOS expects that the wakeup sources are cleared and set to D3 for all wakeup devices when the system is going to sleep or power off, but the current xhci driver doesn't do this properly (partly intentionally).
This patch introduces a new quirk, XHCI_SPURIOUS_WAKEUP, for fixing the spurious wakeups at S5 by calling xhci_reset() in the xhci shutdown ops as done in xhci_stop(), and setting the device to PCI D3 at shutdown and remove ops.
The PCI D3 call is based on the initial fix patch by Oliver Neukum.
[Note: Sarah changed the quirk name from XHCI_HSW_SPURIOUS_WAKEUP to XHCI_SPURIOUS_WAKEUP, since none of the other quirks have system names in them. Sarah also fixed a collision with a quirk submitted around the same time, by changing the xhci->quirks bit from 17 to 18.]
This patch should be backported to kernels as old as 3.0, that contain the commit 1c12443ab8eba71a658fae4572147e56d1f84f66 "xhci: Add Lynx Point to list of Intel switchable hosts."
Cc: Oliver Neukum <oneukum@suse.de> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Cc: stable@vger.kernel.org Signed-off-by: Rick Salevsky <rsalevsky@suse.de> --- drivers/usb/host/xhci-pci.c | 17 +++++++++++++++++ drivers/usb/host/xhci.c | 7 +++++++ drivers/usb/host/xhci.h | 1 + 3 files changed, 25 insertions(+)
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 159e3c6..794f5f9 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -34,6 +34,9 @@ #define PCI_VENDOR_ID_ETRON 0x1b6f #define PCI_DEVICE_ID_ASROCK_P67 0x7023
+#define PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI 0x8c31 +#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31 + static const char hcd_name[] = "xhci_hcd";
/* called after powerup, by probe or system-pm "wakeup" */ @@ -107,6 +110,15 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) xhci->quirks |= XHCI_SPURIOUS_REBOOT; xhci->quirks |= XHCI_AVOID_BEI; } + if (pdev->vendor == PCI_VENDOR_ID_INTEL && + (pdev->device == PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI || + pdev->device == PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI)) { + /* Workaround for occasional spurious wakeups from S5 (or + * any other sleep) on Haswell machines with LPT and LPT-LP + * with the new Intel BIOS + */ + xhci->quirks |= XHCI_SPURIOUS_WAKEUP; + } if (pdev->vendor == PCI_VENDOR_ID_ETRON && pdev->device == PCI_DEVICE_ID_ASROCK_P67) { xhci->quirks |= XHCI_RESET_ON_RESUME; @@ -213,6 +225,11 @@ static void xhci_pci_remove(struct pci_dev *dev) usb_put_hcd(xhci->shared_hcd); } usb_hcd_pci_remove(dev); + + /* Workaround for spurious wakeups at shutdown with HSW */ + if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) + pci_set_power_state(dev, PCI_D3hot); + kfree(xhci); }
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index d1fc37f..33d62ef 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -780,12 +780,19 @@ void xhci_shutdown(struct usb_hcd *hcd)
spin_lock_irq(&xhci->lock); xhci_halt(xhci); + /* Workaround for spurious wakeups at shutdown with HSW */ + if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) + xhci_reset(xhci); spin_unlock_irq(&xhci->lock);
xhci_cleanup_msix(xhci);
xhci_dbg(xhci, "xhci_shutdown completed - status = %x\n", xhci_readl(xhci, &xhci->op_regs->status)); + + /* Yet another workaround for spurious wakeups at shutdown with HSW */ + if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) + pci_set_power_state(to_pci_dev(hcd->self.controller), PCI_D3hot); }
#ifdef CONFIG_PM diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index e63645d..e044a39 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1543,6 +1543,7 @@ struct xhci_hcd { #define XHCI_COMP_MODE_QUIRK (1 << 14) #define XHCI_AVOID_BEI (1 << 15) #define XHCI_PLAT (1 << 16) +#define XHCI_SPURIOUS_WAKEUP (1 << 18) unsigned int num_active_eps; unsigned int limit_active_eps; /* There are two roothubs to keep track of bus suspend info for */ -- 1.7.12.4
-- To unsubscribe, e-mail: opensuse-kernel+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-kernel+owner@opensuse.org
Am Donnerstag, den 28.11.2013, 18:53 +0100 schrieb Takashi Iwai:
At Thu, 28 Nov 2013 14:51:20 +0100, Rick Salevsky wrote:
[1 <text/plain; UTF-8 (8bit)>] Hey, here is a patch/fix for openSuse 13.1 that will fix the following issue:
Haswell LynxPoint and LynxPoint-LP with the recent Intel BIOS show mysterious wakeups after shutdown occasionally. After discussing with BIOS engineers, they explained that the new BIOS expects that the wakeup sources are cleared and set to D3 for all wakeup devices when the system is going to sleep or power off, but the current xhci driver doesn't do this properly (partly intentionally).
This patch introduces a new quirk, XHCI_HSW_SPURIOUS_WAKEUP, for fixing the spurious wakeups at S5 by calling xhci_stop() instead of its stripped version in the xhci shutdown ops, and setting the device to PCI D3 at shutdown and remove ops.
Could you add required tags like References and Git-commit, and resubmit?
Ok, no problem the new patch is attached.
thanks,
Takashi
Ciao, -- Rick Salevsky, Trainee SUSE LINUX GmbH, Maxfeldstr. 5, D-90409 Nuernberg Tel: +49-911-74053-538 - rsalevsky@suse.com SUSE LINUX GmbH, GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer, HRB 21284 (AG Nürnberg) [2 xhci-Fix-spurious-wakeups-after-S5-on-Haswell.patch <text/x-patch; UTF-8 (7bit)>]
From fa10dee546b60b6281468db375816451618c2194 Mon Sep 17 00:00:00 2001 From: Takashi Iwai <tiwai@suse.de> Date: Thu, 12 Sep 2013 08:11:06 +0200 Subject: [PATCH] xhci: Fix spurious wakeups after S5 on Haswell
commit 638298dc66ea36623dbc2757a24fc2c4ab41b016 upstream.
Haswell LynxPoint and LynxPoint-LP with the recent Intel BIOS show mysterious wakeups after shutdown occasionally. After discussing with BIOS engineers, they explained that the new BIOS expects that the wakeup sources are cleared and set to D3 for all wakeup devices when the system is going to sleep or power off, but the current xhci driver doesn't do this properly (partly intentionally).
This patch introduces a new quirk, XHCI_SPURIOUS_WAKEUP, for fixing the spurious wakeups at S5 by calling xhci_reset() in the xhci shutdown ops as done in xhci_stop(), and setting the device to PCI D3 at shutdown and remove ops.
The PCI D3 call is based on the initial fix patch by Oliver Neukum.
[Note: Sarah changed the quirk name from XHCI_HSW_SPURIOUS_WAKEUP to XHCI_SPURIOUS_WAKEUP, since none of the other quirks have system names in them. Sarah also fixed a collision with a quirk submitted around the same time, by changing the xhci->quirks bit from 17 to 18.]
This patch should be backported to kernels as old as 3.0, that contain the commit 1c12443ab8eba71a658fae4572147e56d1f84f66 "xhci: Add Lynx Point to list of Intel switchable hosts."
Cc: Oliver Neukum <oneukum@suse.de> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Cc: stable@vger.kernel.org Signed-off-by: Rick Salevsky <rsalevsky@suse.de> --- drivers/usb/host/xhci-pci.c | 17 +++++++++++++++++ drivers/usb/host/xhci.c | 7 +++++++ drivers/usb/host/xhci.h | 1 + 3 files changed, 25 insertions(+)
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 159e3c6..794f5f9 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -34,6 +34,9 @@ #define PCI_VENDOR_ID_ETRON 0x1b6f #define PCI_DEVICE_ID_ASROCK_P67 0x7023
+#define PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI 0x8c31 +#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31 + static const char hcd_name[] = "xhci_hcd";
/* called after powerup, by probe or system-pm "wakeup" */ @@ -107,6 +110,15 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) xhci->quirks |= XHCI_SPURIOUS_REBOOT; xhci->quirks |= XHCI_AVOID_BEI; } + if (pdev->vendor == PCI_VENDOR_ID_INTEL && + (pdev->device == PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI || + pdev->device == PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI)) { + /* Workaround for occasional spurious wakeups from S5 (or + * any other sleep) on Haswell machines with LPT and LPT-LP + * with the new Intel BIOS + */ + xhci->quirks |= XHCI_SPURIOUS_WAKEUP; + } if (pdev->vendor == PCI_VENDOR_ID_ETRON && pdev->device == PCI_DEVICE_ID_ASROCK_P67) { xhci->quirks |= XHCI_RESET_ON_RESUME; @@ -213,6 +225,11 @@ static void xhci_pci_remove(struct pci_dev *dev) usb_put_hcd(xhci->shared_hcd); } usb_hcd_pci_remove(dev); + + /* Workaround for spurious wakeups at shutdown with HSW */ + if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) + pci_set_power_state(dev, PCI_D3hot); + kfree(xhci); }
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index d1fc37f..33d62ef 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -780,12 +780,19 @@ void xhci_shutdown(struct usb_hcd *hcd)
spin_lock_irq(&xhci->lock); xhci_halt(xhci); + /* Workaround for spurious wakeups at shutdown with HSW */ + if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) + xhci_reset(xhci); spin_unlock_irq(&xhci->lock);
xhci_cleanup_msix(xhci);
xhci_dbg(xhci, "xhci_shutdown completed - status = %x\n", xhci_readl(xhci, &xhci->op_regs->status)); + + /* Yet another workaround for spurious wakeups at shutdown with HSW */ + if (xhci->quirks & XHCI_SPURIOUS_WAKEUP) + pci_set_power_state(to_pci_dev(hcd->self.controller), PCI_D3hot); }
#ifdef CONFIG_PM diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index e63645d..e044a39 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1543,6 +1543,7 @@ struct xhci_hcd { #define XHCI_COMP_MODE_QUIRK (1 << 14) #define XHCI_AVOID_BEI (1 << 15) #define XHCI_PLAT (1 << 16) +#define XHCI_SPURIOUS_WAKEUP (1 << 18) unsigned int num_active_eps; unsigned int limit_active_eps; /* There are two roothubs to keep track of bus suspend info for */ -- 1.7.12.4
-- Rick Salevsky, Trainee SUSE LINUX GmbH, Maxfeldstr. 5, D-90409 Nuernberg Tel: +49-911-74053-538 - rsalevsky@suse.com SUSE LINUX GmbH, GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer, HRB 21284 (AG Nürnberg)
At Fri, 29 Nov 2013 12:25:10 +0100, Rick Salevsky wrote:
Am Donnerstag, den 28.11.2013, 18:53 +0100 schrieb Takashi Iwai:
At Thu, 28 Nov 2013 14:51:20 +0100, Rick Salevsky wrote:
[1 <text/plain; UTF-8 (8bit)>] Hey, here is a patch/fix for openSuse 13.1 that will fix the following issue:
Haswell LynxPoint and LynxPoint-LP with the recent Intel BIOS show mysterious wakeups after shutdown occasionally. After discussing with BIOS engineers, they explained that the new BIOS expects that the wakeup sources are cleared and set to D3 for all wakeup devices when the system is going to sleep or power off, but the current xhci driver doesn't do this properly (partly intentionally).
This patch introduces a new quirk, XHCI_HSW_SPURIOUS_WAKEUP, for fixing the spurious wakeups at S5 by calling xhci_stop() instead of its stripped version in the xhci shutdown ops, and setting the device to PCI D3 at shutdown and remove ops.
Could you add required tags like References and Git-commit, and resubmit?
Ok, no problem the new patch is attached.
Thanks, committed to git tree now. Takashi -- To unsubscribe, e-mail: opensuse-kernel+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-kernel+owner@opensuse.org
participants (2)
-
Rick Salevsky
-
Takashi Iwai