diff options
author | Alan Cox <alan@lxorguk.ukuu.org.uk> | 2008-07-24 12:18:38 -0400 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2008-07-28 18:12:11 -0400 |
commit | 979b1791e5b8f8b556faeec4c48339e7ed63af9f (patch) | |
tree | 30990937096bb25aa8349dae7285e70f268a767a | |
parent | 362b7077a5546b42131af15ba4776f30c9a72d0c (diff) |
PCI: add D3 power state avoidance quirk
Libata has some hacks to deal with certain controllers going silly in D3
state. The right way to handle this is to keep a PCI device flag for
such devices. That can then be generalised for no ATA devices with power
problems.
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
-rw-r--r-- | drivers/pci/pci.c | 4 | ||||
-rw-r--r-- | drivers/pci/quirks.c | 13 | ||||
-rw-r--r-- | include/linux/pci.h | 2 |
3 files changed, 19 insertions, 0 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index c95f77d6571..0a3d856833f 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -572,6 +572,10 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
572 | if (!ret) | 572 | if (!ret) |
573 | pci_update_current_state(dev); | 573 | pci_update_current_state(dev); |
574 | } | 574 | } |
575 | /* This device is quirked not to be put into D3, so | ||
576 | don't put it in D3 */ | ||
577 | if (state == PCI_D3hot && (dev->dev_flags & PCI_DEV_FLAGS_NO_D3)) | ||
578 | return 0; | ||
575 | 579 | ||
576 | error = pci_raw_set_power_state(dev, state); | 580 | error = pci_raw_set_power_state(dev, state); |
577 | 581 | ||
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 12d489395fa..0fb36507428 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -923,6 +923,19 @@ static void __init quirk_ide_samemode(struct pci_dev *pdev) | |||
923 | } | 923 | } |
924 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10, quirk_ide_samemode); | 924 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10, quirk_ide_samemode); |
925 | 925 | ||
926 | /* | ||
927 | * Some ATA devices break if put into D3 | ||
928 | */ | ||
929 | |||
930 | static void __devinit quirk_no_ata_d3(struct pci_dev *pdev) | ||
931 | { | ||
932 | /* Quirk the legacy ATA devices only. The AHCI ones are ok */ | ||
933 | if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) | ||
934 | pdev->dev_flags |= PCI_DEV_FLAGS_NO_D3; | ||
935 | } | ||
936 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_ANY_ID, quirk_no_ata_d3); | ||
937 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, PCI_ANY_ID, quirk_no_ata_d3); | ||
938 | |||
926 | /* This was originally an Alpha specific thing, but it really fits here. | 939 | /* This was originally an Alpha specific thing, but it really fits here. |
927 | * The i82375 PCI/EISA bridge appears as non-classified. Fix that. | 940 | * The i82375 PCI/EISA bridge appears as non-classified. Fix that. |
928 | */ | 941 | */ |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 1d296d31abe..825be3878f6 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -124,6 +124,8 @@ enum pci_dev_flags { | |||
124 | * generation too. | 124 | * generation too. |
125 | */ | 125 | */ |
126 | PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG = (__force pci_dev_flags_t) 1, | 126 | PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG = (__force pci_dev_flags_t) 1, |
127 | /* Device configuration is irrevocably lost if disabled into D3 */ | ||
128 | PCI_DEV_FLAGS_NO_D3 = (__force pci_dev_flags_t) 2, | ||
127 | }; | 129 | }; |
128 | 130 | ||
129 | typedef unsigned short __bitwise pci_bus_flags_t; | 131 | typedef unsigned short __bitwise pci_bus_flags_t; |