diff options
| -rw-r--r-- | drivers/pci/pci.c | 5 | ||||
| -rw-r--r-- | drivers/pci/quirks.c | 26 | ||||
| -rw-r--r-- | drivers/usb/core/hcd-pci.c | 9 | ||||
| -rw-r--r-- | drivers/usb/host/ehci-pci.c | 8 | ||||
| -rw-r--r-- | include/linux/pci.h | 2 | ||||
| -rw-r--r-- | include/linux/usb/hcd.h | 2 |
6 files changed, 33 insertions, 19 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 447e83472c01..77cb54a65cde 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
| @@ -1744,6 +1744,11 @@ int pci_prepare_to_sleep(struct pci_dev *dev) | |||
| 1744 | if (target_state == PCI_POWER_ERROR) | 1744 | if (target_state == PCI_POWER_ERROR) |
| 1745 | return -EIO; | 1745 | return -EIO; |
| 1746 | 1746 | ||
| 1747 | /* Some devices mustn't be in D3 during system sleep */ | ||
| 1748 | if (target_state == PCI_D3hot && | ||
| 1749 | (dev->dev_flags & PCI_DEV_FLAGS_NO_D3_DURING_SLEEP)) | ||
| 1750 | return 0; | ||
| 1751 | |||
| 1747 | pci_enable_wake(dev, target_state, device_may_wakeup(&dev->dev)); | 1752 | pci_enable_wake(dev, target_state, device_may_wakeup(&dev->dev)); |
| 1748 | 1753 | ||
| 1749 | error = pci_set_power_state(dev, target_state); | 1754 | error = pci_set_power_state(dev, target_state); |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 2a7521677541..194b243a2817 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
| @@ -2929,6 +2929,32 @@ static void __devinit disable_igfx_irq(struct pci_dev *dev) | |||
| 2929 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0102, disable_igfx_irq); | 2929 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0102, disable_igfx_irq); |
| 2930 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq); | 2930 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq); |
| 2931 | 2931 | ||
| 2932 | /* | ||
| 2933 | * The Intel 6 Series/C200 Series chipset's EHCI controllers on many | ||
| 2934 | * ASUS motherboards will cause memory corruption or a system crash | ||
| 2935 | * if they are in D3 while the system is put into S3 sleep. | ||
| 2936 | */ | ||
| 2937 | static void __devinit asus_ehci_no_d3(struct pci_dev *dev) | ||
| 2938 | { | ||
| 2939 | const char *sys_info; | ||
| 2940 | static const char good_Asus_board[] = "P8Z68-V"; | ||
| 2941 | |||
| 2942 | if (dev->dev_flags & PCI_DEV_FLAGS_NO_D3_DURING_SLEEP) | ||
| 2943 | return; | ||
| 2944 | if (dev->subsystem_vendor != PCI_VENDOR_ID_ASUSTEK) | ||
| 2945 | return; | ||
| 2946 | sys_info = dmi_get_system_info(DMI_BOARD_NAME); | ||
| 2947 | if (sys_info && memcmp(sys_info, good_Asus_board, | ||
| 2948 | sizeof(good_Asus_board) - 1) == 0) | ||
| 2949 | return; | ||
| 2950 | |||
| 2951 | dev_info(&dev->dev, "broken D3 during system sleep on ASUS\n"); | ||
| 2952 | dev->dev_flags |= PCI_DEV_FLAGS_NO_D3_DURING_SLEEP; | ||
| 2953 | device_set_wakeup_capable(&dev->dev, false); | ||
| 2954 | } | ||
| 2955 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1c26, asus_ehci_no_d3); | ||
| 2956 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1c2d, asus_ehci_no_d3); | ||
| 2957 | |||
| 2932 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, | 2958 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, |
| 2933 | struct pci_fixup *end) | 2959 | struct pci_fixup *end) |
| 2934 | { | 2960 | { |
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 57ed9e400c06..622b4a48e732 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c | |||
| @@ -493,15 +493,6 @@ static int hcd_pci_suspend_noirq(struct device *dev) | |||
| 493 | 493 | ||
| 494 | pci_save_state(pci_dev); | 494 | pci_save_state(pci_dev); |
| 495 | 495 | ||
| 496 | /* | ||
| 497 | * Some systems crash if an EHCI controller is in D3 during | ||
| 498 | * a sleep transition. We have to leave such controllers in D0. | ||
| 499 | */ | ||
| 500 | if (hcd->broken_pci_sleep) { | ||
| 501 | dev_dbg(dev, "Staying in PCI D0\n"); | ||
| 502 | return retval; | ||
| 503 | } | ||
| 504 | |||
| 505 | /* If the root hub is dead rather than suspended, disallow remote | 496 | /* If the root hub is dead rather than suspended, disallow remote |
| 506 | * wakeup. usb_hc_died() should ensure that both hosts are marked as | 497 | * wakeup. usb_hc_died() should ensure that both hosts are marked as |
| 507 | * dying, so we only need to check the primary roothub. | 498 | * 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 bc94d7bf072d..123481793a47 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 d8c379dba6ad..fefb4e19bf6a 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
| @@ -176,6 +176,8 @@ enum pci_dev_flags { | |||
| 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 | /* Provide indication device is assigned by a Virtual Machine Manager */ | 177 | /* Provide indication device is assigned by a Virtual Machine Manager */ |
| 178 | PCI_DEV_FLAGS_ASSIGNED = (__force pci_dev_flags_t) 4, | 178 | PCI_DEV_FLAGS_ASSIGNED = (__force pci_dev_flags_t) 4, |
| 179 | /* Device causes system crash if in D3 during S3 sleep */ | ||
| 180 | PCI_DEV_FLAGS_NO_D3_DURING_SLEEP = (__force pci_dev_flags_t) 8, | ||
| 179 | }; | 181 | }; |
| 180 | 182 | ||
| 181 | enum pci_irq_reroute_variant { | 183 | enum pci_irq_reroute_variant { |
diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 7f855d50cdf5..49b3ac29726a 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h | |||
| @@ -126,8 +126,6 @@ struct usb_hcd { | |||
| 126 | unsigned wireless:1; /* Wireless USB HCD */ | 126 | unsigned wireless:1; /* Wireless USB HCD */ |
| 127 | unsigned authorized_default:1; | 127 | unsigned authorized_default:1; |
| 128 | unsigned has_tt:1; /* Integrated TT in root hub */ | 128 | unsigned has_tt:1; /* Integrated TT in root hub */ |
| 129 | unsigned broken_pci_sleep:1; /* Don't put the | ||
| 130 | controller in PCI-D3 for system sleep */ | ||
| 131 | 129 | ||
| 132 | unsigned int irq; /* irq allocated */ | 130 | unsigned int irq; /* irq allocated */ |
| 133 | void __iomem *regs; /* device memory/io */ | 131 | void __iomem *regs; /* device memory/io */ |
