aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/pci.c5
-rw-r--r--drivers/pci/quirks.c26
-rw-r--r--drivers/usb/core/hcd-pci.c9
-rw-r--r--drivers/usb/host/ehci-pci.c8
-rw-r--r--include/linux/pci.h2
-rw-r--r--include/linux/usb/hcd.h2
6 files changed, 33 insertions, 19 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index d549bbc93cd..bf401aead87 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -1682,6 +1682,11 @@ int pci_prepare_to_sleep(struct pci_dev *dev)
1682 if (target_state == PCI_POWER_ERROR) 1682 if (target_state == PCI_POWER_ERROR)
1683 return -EIO; 1683 return -EIO;
1684 1684
1685 /* Some devices mustn't be in D3 during system sleep */
1686 if (target_state == PCI_D3hot &&
1687 (dev->dev_flags & PCI_DEV_FLAGS_NO_D3_DURING_SLEEP))
1688 return 0;
1689
1685 pci_enable_wake(dev, target_state, device_may_wakeup(&dev->dev)); 1690 pci_enable_wake(dev, target_state, device_may_wakeup(&dev->dev));
1686 1691
1687 error = pci_set_power_state(dev, target_state); 1692 error = pci_set_power_state(dev, target_state);
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index a6b07ddad71..975af4353e7 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -2856,6 +2856,32 @@ static void __devinit disable_igfx_irq(struct pci_dev *dev)
2856DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0102, disable_igfx_irq); 2856DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0102, disable_igfx_irq);
2857DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq); 2857DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq);
2858 2858
2859/*
2860 * The Intel 6 Series/C200 Series chipset's EHCI controllers on many
2861 * ASUS motherboards will cause memory corruption or a system crash
2862 * if they are in D3 while the system is put into S3 sleep.
2863 */
2864static void __devinit asus_ehci_no_d3(struct pci_dev *dev)
2865{
2866 const char *sys_info;
2867 static const char good_Asus_board[] = "P8Z68-V";
2868
2869 if (dev->dev_flags & PCI_DEV_FLAGS_NO_D3_DURING_SLEEP)
2870 return;
2871 if (dev->subsystem_vendor != PCI_VENDOR_ID_ASUSTEK)
2872 return;
2873 sys_info = dmi_get_system_info(DMI_BOARD_NAME);
2874 if (sys_info && memcmp(sys_info, good_Asus_board,
2875 sizeof(good_Asus_board) - 1) == 0)
2876 return;
2877
2878 dev_info(&dev->dev, "broken D3 during system sleep on ASUS\n");
2879 dev->dev_flags |= PCI_DEV_FLAGS_NO_D3_DURING_SLEEP;
2880 device_set_wakeup_capable(&dev->dev, false);
2881}
2882DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1c26, asus_ehci_no_d3);
2883DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1c2d, asus_ehci_no_d3);
2884
2859static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, 2885static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f,
2860 struct pci_fixup *end) 2886 struct pci_fixup *end)
2861{ 2887{
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
index aa7bbbcf9d8..6c1642b382f 100644
--- a/drivers/usb/core/hcd-pci.c
+++ b/drivers/usb/core/hcd-pci.c
@@ -495,15 +495,6 @@ static int hcd_pci_suspend_noirq(struct device *dev)
495 495
496 pci_save_state(pci_dev); 496 pci_save_state(pci_dev);
497 497
498 /*
499 * Some systems crash if an EHCI controller is in D3 during
500 * a sleep transition. We have to leave such controllers in D0.
501 */
502 if (hcd->broken_pci_sleep) {
503 dev_dbg(dev, "Staying in PCI D0\n");
504 return retval;
505 }
506
507 /* If the root hub is dead rather than suspended, disallow remote 498 /* If the root hub is dead rather than suspended, disallow remote
508 * wakeup. usb_hc_died() should ensure that both hosts are marked as 499 * wakeup. usb_hc_died() should ensure that both hosts are marked as
509 * dying, so we only need to check the primary roothub. 500 * dying, so we only need to check the primary roothub.
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index efb9efcffe4..f76831480c6 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -144,14 +144,6 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
144 hcd->has_tt = 1; 144 hcd->has_tt = 1;
145 tdi_reset(ehci); 145 tdi_reset(ehci);
146 } 146 }
147 if (pdev->subsystem_vendor == PCI_VENDOR_ID_ASUSTEK) {
148 /* EHCI #1 or #2 on 6 Series/C200 Series chipset */
149 if (pdev->device == 0x1c26 || pdev->device == 0x1c2d) {
150 ehci_info(ehci, "broken D3 during system sleep on ASUS\n");
151 hcd->broken_pci_sleep = 1;
152 device_set_wakeup_capable(&pdev->dev, false);
153 }
154 }
155 break; 147 break;
156 case PCI_VENDOR_ID_TDI: 148 case PCI_VENDOR_ID_TDI:
157 if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) { 149 if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) {
diff --git a/include/linux/pci.h b/include/linux/pci.h
index c446b5ca2d3..ff5970b7a17 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -174,6 +174,8 @@ enum pci_dev_flags {
174 PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG = (__force pci_dev_flags_t) 1, 174 PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG = (__force pci_dev_flags_t) 1,
175 /* Device configuration is irrevocably lost if disabled into D3 */ 175 /* Device configuration is irrevocably lost if disabled into D3 */
176 PCI_DEV_FLAGS_NO_D3 = (__force pci_dev_flags_t) 2, 176 PCI_DEV_FLAGS_NO_D3 = (__force pci_dev_flags_t) 2,
177 /* Device causes system crash if in D3 during S3 sleep */
178 PCI_DEV_FLAGS_NO_D3_DURING_SLEEP = (__force pci_dev_flags_t) 8,
177}; 179};
178 180
179enum pci_irq_reroute_variant { 181enum pci_irq_reroute_variant {
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
index 32ba8c55b3a..c0ecc5a2ef9 100644
--- a/include/linux/usb/hcd.h
+++ b/include/linux/usb/hcd.h
@@ -128,8 +128,6 @@ struct usb_hcd {
128 unsigned wireless:1; /* Wireless USB HCD */ 128 unsigned wireless:1; /* Wireless USB HCD */
129 unsigned authorized_default:1; 129 unsigned authorized_default:1;
130 unsigned has_tt:1; /* Integrated TT in root hub */ 130 unsigned has_tt:1; /* Integrated TT in root hub */
131 unsigned broken_pci_sleep:1; /* Don't put the
132 controller in PCI-D3 for system sleep */
133 131
134 int irq; /* irq allocated */ 132 int irq; /* irq allocated */
135 void __iomem *regs; /* device memory/io */ 133 void __iomem *regs; /* device memory/io */