aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Cox <alan@lxorguk.ukuu.org.uk>2008-07-24 12:18:38 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2008-07-28 18:12:11 -0400
commit979b1791e5b8f8b556faeec4c48339e7ed63af9f (patch)
tree30990937096bb25aa8349dae7285e70f268a767a
parent362b7077a5546b42131af15ba4776f30c9a72d0c (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.c4
-rw-r--r--drivers/pci/quirks.c13
-rw-r--r--include/linux/pci.h2
3 files changed, 19 insertions, 0 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index c95f77d65718..0a3d856833fc 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 12d489395fad..0fb365074288 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}
924DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10, quirk_ide_samemode); 924DECLARE_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
930static 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}
936DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_ANY_ID, quirk_no_ata_d3);
937DECLARE_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 1d296d31abe0..825be3878f68 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
129typedef unsigned short __bitwise pci_bus_flags_t; 131typedef unsigned short __bitwise pci_bus_flags_t;