diff options
author | Kristen Carlson Accardi <kristen.c.accardi@intel.com> | 2006-07-12 11:59:00 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-07-12 19:05:48 -0400 |
commit | ffadcc2ff42ecedf71ea67d9051ff028927aed08 (patch) | |
tree | 540351be72173f69c552c05dfeffd0804ca0bd6b /drivers/pci/pci.c | |
parent | 6f0312fd7e0e6f96fd847b0b2e1e0d2d2e8ef89d (diff) |
[PATCH] PCI: PCIE power management quirk
When changing power states from D0->DX and then from DX->D0, some
Intel PCIE chipsets will cause a device reset to occur. This will
cause problems for any D State other than D3, since any state
information that the driver will expect to be present coming from
a D1 or D2 state will have been cleared. This patch addes a
flag to the pci_dev structure to indicate that devices should
not use states D1 or D2, and will set that flag for the affected
chipsets. This patch also modifies pci_set_power_state() so that
when a device driver tries to set the power state on
a device that is downstream from an affected chipset, or on one
of the affected devices it only allows state changes to or
from D0 & D3. In addition, this patch allows the delay time
between D3->D0 to be changed via a quirk. These chipsets also
need additional time to change states beyond the normal 10ms.
Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r-- | drivers/pci/pci.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index cf57d7de3765..9f79dd6d51ab 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <asm/dma.h> /* isa_dma_bridge_buggy */ | 19 | #include <asm/dma.h> /* isa_dma_bridge_buggy */ |
20 | #include "pci.h" | 20 | #include "pci.h" |
21 | 21 | ||
22 | unsigned int pci_pm_d3_delay = 10; | ||
22 | 23 | ||
23 | /** | 24 | /** |
24 | * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children | 25 | * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children |
@@ -313,6 +314,14 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
313 | } else if (dev->current_state == state) | 314 | } else if (dev->current_state == state) |
314 | return 0; /* we're already there */ | 315 | return 0; /* we're already there */ |
315 | 316 | ||
317 | /* | ||
318 | * If the device or the parent bridge can't support PCI PM, ignore | ||
319 | * the request if we're doing anything besides putting it into D0 | ||
320 | * (which would only happen on boot). | ||
321 | */ | ||
322 | if ((state == PCI_D1 || state == PCI_D2) && pci_no_d1d2(dev)) | ||
323 | return 0; | ||
324 | |||
316 | /* find PCI PM capability in list */ | 325 | /* find PCI PM capability in list */ |
317 | pm = pci_find_capability(dev, PCI_CAP_ID_PM); | 326 | pm = pci_find_capability(dev, PCI_CAP_ID_PM); |
318 | 327 | ||
@@ -363,7 +372,7 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
363 | /* Mandatory power management transition delays */ | 372 | /* Mandatory power management transition delays */ |
364 | /* see PCI PM 1.1 5.6.1 table 18 */ | 373 | /* see PCI PM 1.1 5.6.1 table 18 */ |
365 | if (state == PCI_D3hot || dev->current_state == PCI_D3hot) | 374 | if (state == PCI_D3hot || dev->current_state == PCI_D3hot) |
366 | msleep(10); | 375 | msleep(pci_pm_d3_delay); |
367 | else if (state == PCI_D2 || dev->current_state == PCI_D2) | 376 | else if (state == PCI_D2 || dev->current_state == PCI_D2) |
368 | udelay(200); | 377 | udelay(200); |
369 | 378 | ||