diff options
-rw-r--r-- | drivers/pci/pcie/aspm.c | 13 | ||||
-rw-r--r-- | drivers/pci/probe.c | 3 | ||||
-rw-r--r-- | include/linux/pci_regs.h | 1 |
3 files changed, 16 insertions, 1 deletions
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 759c51a4e399..704605298c5e 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c | |||
@@ -510,6 +510,7 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev) | |||
510 | { | 510 | { |
511 | struct pci_dev *child_dev; | 511 | struct pci_dev *child_dev; |
512 | int child_pos; | 512 | int child_pos; |
513 | u32 reg32; | ||
513 | 514 | ||
514 | /* | 515 | /* |
515 | * Some functions in a slot might not all be PCIE functions, very | 516 | * Some functions in a slot might not all be PCIE functions, very |
@@ -519,6 +520,18 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev) | |||
519 | child_pos = pci_find_capability(child_dev, PCI_CAP_ID_EXP); | 520 | child_pos = pci_find_capability(child_dev, PCI_CAP_ID_EXP); |
520 | if (!child_pos) | 521 | if (!child_pos) |
521 | return -EINVAL; | 522 | return -EINVAL; |
523 | |||
524 | /* | ||
525 | * Disable ASPM for pre-1.1 PCIe device, we follow MS to use | ||
526 | * RBER bit to determine if a function is 1.1 version device | ||
527 | */ | ||
528 | pci_read_config_dword(child_dev, child_pos + PCI_EXP_DEVCAP, | ||
529 | ®32); | ||
530 | if (!(reg32 & PCI_EXP_DEVCAP_RBER)) { | ||
531 | printk("Pre-1.1 PCIe device detected, " | ||
532 | "disable ASPM for %s\n", pci_name(pdev)); | ||
533 | return -EINVAL; | ||
534 | } | ||
522 | } | 535 | } |
523 | return 0; | 536 | return 0; |
524 | } | 537 | } |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 203630065839..7098dfb07449 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -1057,7 +1057,8 @@ int pci_scan_slot(struct pci_bus *bus, int devfn) | |||
1057 | } | 1057 | } |
1058 | } | 1058 | } |
1059 | 1059 | ||
1060 | if (bus->self) | 1060 | /* only one slot has pcie device */ |
1061 | if (bus->self && nr) | ||
1061 | pcie_aspm_init_link_state(bus->self); | 1062 | pcie_aspm_init_link_state(bus->self); |
1062 | 1063 | ||
1063 | return nr; | 1064 | return nr; |
diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h index 19958b929905..450684f7eaac 100644 --- a/include/linux/pci_regs.h +++ b/include/linux/pci_regs.h | |||
@@ -374,6 +374,7 @@ | |||
374 | #define PCI_EXP_DEVCAP_ATN_BUT 0x1000 /* Attention Button Present */ | 374 | #define PCI_EXP_DEVCAP_ATN_BUT 0x1000 /* Attention Button Present */ |
375 | #define PCI_EXP_DEVCAP_ATN_IND 0x2000 /* Attention Indicator Present */ | 375 | #define PCI_EXP_DEVCAP_ATN_IND 0x2000 /* Attention Indicator Present */ |
376 | #define PCI_EXP_DEVCAP_PWR_IND 0x4000 /* Power Indicator Present */ | 376 | #define PCI_EXP_DEVCAP_PWR_IND 0x4000 /* Power Indicator Present */ |
377 | #define PCI_EXP_DEVCAP_RBER 0x8000 /* Role-Based Error Reporting */ | ||
377 | #define PCI_EXP_DEVCAP_PWR_VAL 0x3fc0000 /* Slot Power Limit Value */ | 378 | #define PCI_EXP_DEVCAP_PWR_VAL 0x3fc0000 /* Slot Power Limit Value */ |
378 | #define PCI_EXP_DEVCAP_PWR_SCL 0xc000000 /* Slot Power Limit Scale */ | 379 | #define PCI_EXP_DEVCAP_PWR_SCL 0xc000000 /* Slot Power Limit Scale */ |
379 | #define PCI_EXP_DEVCTL 8 /* Device Control */ | 380 | #define PCI_EXP_DEVCTL 8 /* Device Control */ |