aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/pci.c11
-rw-r--r--drivers/pci/pci.h10
-rw-r--r--drivers/pci/quirks.c31
-rw-r--r--include/linux/pci.h1
4 files changed, 51 insertions, 2 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
22unsigned 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
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 9cc842b666eb..08d58fc78ee1 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -47,7 +47,7 @@ extern int pci_msi_quirk;
47#else 47#else
48#define pci_msi_quirk 0 48#define pci_msi_quirk 0
49#endif 49#endif
50 50extern unsigned int pci_pm_d3_delay;
51#ifdef CONFIG_PCI_MSI 51#ifdef CONFIG_PCI_MSI
52void disable_msi_mode(struct pci_dev *dev, int pos, int type); 52void disable_msi_mode(struct pci_dev *dev, int pos, int type);
53void pci_no_msi(void); 53void pci_no_msi(void);
@@ -66,7 +66,15 @@ static inline int pci_save_msix_state(struct pci_dev *dev) { return 0; }
66static inline void pci_restore_msi_state(struct pci_dev *dev) {} 66static inline void pci_restore_msi_state(struct pci_dev *dev) {}
67static inline void pci_restore_msix_state(struct pci_dev *dev) {} 67static inline void pci_restore_msix_state(struct pci_dev *dev) {}
68#endif 68#endif
69static inline int pci_no_d1d2(struct pci_dev *dev)
70{
71 unsigned int parent_dstates = 0;
69 72
73 if (dev->bus->self)
74 parent_dstates = dev->bus->self->no_d1d2;
75 return (dev->no_d1d2 || parent_dstates);
76
77}
70extern int pcie_mch_quirk; 78extern int pcie_mch_quirk;
71extern struct device_attribute pci_dev_attrs[]; 79extern struct device_attribute pci_dev_attrs[];
72extern struct class_device_attribute class_device_attr_cpuaffinity; 80extern struct class_device_attribute class_device_attr_cpuaffinity;
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 53a887e1014c..e3c78c39b7e4 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -1418,6 +1418,37 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXH_0, quirk_pc
1418DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXH_1, quirk_pcie_pxh); 1418DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXH_1, quirk_pcie_pxh);
1419DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXHV, quirk_pcie_pxh); 1419DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PXHV, quirk_pcie_pxh);
1420 1420
1421/*
1422 * Some Intel PCI Express chipsets have trouble with downstream
1423 * device power management.
1424 */
1425static void quirk_intel_pcie_pm(struct pci_dev * dev)
1426{
1427 pci_pm_d3_delay = 120;
1428 dev->no_d1d2 = 1;
1429}
1430
1431DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x25e2, quirk_intel_pcie_pm);
1432DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x25e3, quirk_intel_pcie_pm);
1433DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x25e4, quirk_intel_pcie_pm);
1434DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x25e5, quirk_intel_pcie_pm);
1435DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x25e6, quirk_intel_pcie_pm);
1436DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x25e7, quirk_intel_pcie_pm);
1437DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x25f7, quirk_intel_pcie_pm);
1438DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x25f8, quirk_intel_pcie_pm);
1439DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x25f9, quirk_intel_pcie_pm);
1440DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x25fa, quirk_intel_pcie_pm);
1441DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2601, quirk_intel_pcie_pm);
1442DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2602, quirk_intel_pcie_pm);
1443DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2603, quirk_intel_pcie_pm);
1444DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2604, quirk_intel_pcie_pm);
1445DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2605, quirk_intel_pcie_pm);
1446DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2606, quirk_intel_pcie_pm);
1447DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2607, quirk_intel_pcie_pm);
1448DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2608, quirk_intel_pcie_pm);
1449DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2609, quirk_intel_pcie_pm);
1450DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x260a, quirk_intel_pcie_pm);
1451DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x260b, quirk_intel_pcie_pm);
1421 1452
1422/* 1453/*
1423 * Fixup the cardbus bridges on the IBM Dock II docking station 1454 * Fixup the cardbus bridges on the IBM Dock II docking station
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 983fca251b25..8565b81d7fbc 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -161,6 +161,7 @@ struct pci_dev {
161 unsigned int is_enabled:1; /* pci_enable_device has been called */ 161 unsigned int is_enabled:1; /* pci_enable_device has been called */
162 unsigned int is_busmaster:1; /* device is busmaster */ 162 unsigned int is_busmaster:1; /* device is busmaster */
163 unsigned int no_msi:1; /* device may not use msi */ 163 unsigned int no_msi:1; /* device may not use msi */
164 unsigned int no_d1d2:1; /* only allow d0 or d3 */
164 unsigned int block_ucfg_access:1; /* userspace config space access is blocked */ 165 unsigned int block_ucfg_access:1; /* userspace config space access is blocked */
165 unsigned int broken_parity_status:1; /* Device generates false positive parity */ 166 unsigned int broken_parity_status:1; /* Device generates false positive parity */
166 unsigned int msi_enabled:1; 167 unsigned int msi_enabled:1;