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 */ |
