diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-01-02 20:44:29 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-01-02 20:44:29 -0500 |
commit | 080a62e2ceec28163194facb837d6388983aae5d (patch) | |
tree | c39ea5bd760383e2300057adcc112ea3be6ce4a4 | |
parent | 8a7eab2b54b349d005181fd971cfa027b1976c7b (diff) | |
parent | 812089e01b9f65f90fc8fc670d8cce72a0e01fbb (diff) |
Merge tag '3.8-pci-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI updates from Bjorn Helgaas:
"Some fixes for v3.8. They include a fix for the new SR-IOV sysfs
management support, an expanded quirk for Ricoh SD card readers, a
Stratus DMI quirk fix, and a PME polling fix."
* tag '3.8-pci-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci:
PCI: Reduce Ricoh 0xe822 SD card reader base clock frequency to 50MHz
PCI/PM: Do not suspend port if any subordinate device needs PME polling
PCI: Add PCIe Link Capability link speed and width names
PCI: Work around Stratus ftServer broken PCIe hierarchy (fix DMI check)
PCI: Remove spurious error for sriov_numvfs store and simplify flow
-rw-r--r-- | arch/x86/pci/common.c | 3 | ||||
-rw-r--r-- | drivers/pci/pci-sysfs.c | 85 | ||||
-rw-r--r-- | drivers/pci/pcie/portdrv_pci.c | 20 | ||||
-rw-r--r-- | drivers/pci/quirks.c | 7 | ||||
-rw-r--r-- | include/linux/pci_ids.h | 1 | ||||
-rw-r--r-- | include/uapi/linux/pci_regs.h | 2 |
6 files changed, 63 insertions, 55 deletions
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index 1b1dda90a94..412e1286d1f 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c | |||
@@ -434,7 +434,8 @@ static const struct dmi_system_id __devinitconst pciprobe_dmi_table[] = { | |||
434 | .callback = set_scan_all, | 434 | .callback = set_scan_all, |
435 | .ident = "Stratus/NEC ftServer", | 435 | .ident = "Stratus/NEC ftServer", |
436 | .matches = { | 436 | .matches = { |
437 | DMI_MATCH(DMI_SYS_VENDOR, "ftServer"), | 437 | DMI_MATCH(DMI_SYS_VENDOR, "Stratus"), |
438 | DMI_MATCH(DMI_PRODUCT_NAME, "ftServer"), | ||
438 | }, | 439 | }, |
439 | }, | 440 | }, |
440 | {} | 441 | {} |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 05b78b16d20..9c6e9bb674e 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -422,77 +422,60 @@ static ssize_t sriov_numvfs_show(struct device *dev, | |||
422 | } | 422 | } |
423 | 423 | ||
424 | /* | 424 | /* |
425 | * num_vfs > 0; number of vfs to enable | 425 | * num_vfs > 0; number of VFs to enable |
426 | * num_vfs = 0; disable all vfs | 426 | * num_vfs = 0; disable all VFs |
427 | * | 427 | * |
428 | * Note: SRIOV spec doesn't allow partial VF | 428 | * Note: SRIOV spec doesn't allow partial VF |
429 | * disable, so its all or none. | 429 | * disable, so it's all or none. |
430 | */ | 430 | */ |
431 | static ssize_t sriov_numvfs_store(struct device *dev, | 431 | static ssize_t sriov_numvfs_store(struct device *dev, |
432 | struct device_attribute *attr, | 432 | struct device_attribute *attr, |
433 | const char *buf, size_t count) | 433 | const char *buf, size_t count) |
434 | { | 434 | { |
435 | struct pci_dev *pdev = to_pci_dev(dev); | 435 | struct pci_dev *pdev = to_pci_dev(dev); |
436 | int num_vfs_enabled = 0; | 436 | int ret; |
437 | int num_vfs; | 437 | u16 num_vfs; |
438 | int ret = 0; | ||
439 | u16 total; | ||
440 | 438 | ||
441 | if (kstrtoint(buf, 0, &num_vfs) < 0) | 439 | ret = kstrtou16(buf, 0, &num_vfs); |
442 | return -EINVAL; | 440 | if (ret < 0) |
441 | return ret; | ||
442 | |||
443 | if (num_vfs > pci_sriov_get_totalvfs(pdev)) | ||
444 | return -ERANGE; | ||
445 | |||
446 | if (num_vfs == pdev->sriov->num_VFs) | ||
447 | return count; /* no change */ | ||
443 | 448 | ||
444 | /* is PF driver loaded w/callback */ | 449 | /* is PF driver loaded w/callback */ |
445 | if (!pdev->driver || !pdev->driver->sriov_configure) { | 450 | if (!pdev->driver || !pdev->driver->sriov_configure) { |
446 | dev_info(&pdev->dev, | 451 | dev_info(&pdev->dev, "Driver doesn't support SRIOV configuration via sysfs\n"); |
447 | "Driver doesn't support SRIOV configuration via sysfs\n"); | ||
448 | return -ENOSYS; | 452 | return -ENOSYS; |
449 | } | 453 | } |
450 | 454 | ||
451 | /* if enabling vf's ... */ | 455 | if (num_vfs == 0) { |
452 | total = pci_sriov_get_totalvfs(pdev); | 456 | /* disable VFs */ |
453 | /* Requested VFs to enable < totalvfs and none enabled already */ | 457 | ret = pdev->driver->sriov_configure(pdev, 0); |
454 | if ((num_vfs > 0) && (num_vfs <= total)) { | 458 | if (ret < 0) |
455 | if (pdev->sriov->num_VFs == 0) { | 459 | return ret; |
456 | num_vfs_enabled = | 460 | return count; |
457 | pdev->driver->sriov_configure(pdev, num_vfs); | ||
458 | if ((num_vfs_enabled >= 0) && | ||
459 | (num_vfs_enabled != num_vfs)) { | ||
460 | dev_warn(&pdev->dev, | ||
461 | "Only %d VFs enabled\n", | ||
462 | num_vfs_enabled); | ||
463 | return count; | ||
464 | } else if (num_vfs_enabled < 0) | ||
465 | /* error code from driver callback */ | ||
466 | return num_vfs_enabled; | ||
467 | } else if (num_vfs == pdev->sriov->num_VFs) { | ||
468 | dev_warn(&pdev->dev, | ||
469 | "%d VFs already enabled; no enable action taken\n", | ||
470 | num_vfs); | ||
471 | return count; | ||
472 | } else { | ||
473 | dev_warn(&pdev->dev, | ||
474 | "%d VFs already enabled. Disable before enabling %d VFs\n", | ||
475 | pdev->sriov->num_VFs, num_vfs); | ||
476 | return -EINVAL; | ||
477 | } | ||
478 | } | 461 | } |
479 | 462 | ||
480 | /* disable vfs */ | 463 | /* enable VFs */ |
481 | if (num_vfs == 0) { | 464 | if (pdev->sriov->num_VFs) { |
482 | if (pdev->sriov->num_VFs != 0) { | 465 | dev_warn(&pdev->dev, "%d VFs already enabled. Disable before enabling %d VFs\n", |
483 | ret = pdev->driver->sriov_configure(pdev, 0); | 466 | pdev->sriov->num_VFs, num_vfs); |
484 | return ret ? ret : count; | 467 | return -EBUSY; |
485 | } else { | ||
486 | dev_warn(&pdev->dev, | ||
487 | "All VFs disabled; no disable action taken\n"); | ||
488 | return count; | ||
489 | } | ||
490 | } | 468 | } |
491 | 469 | ||
492 | dev_err(&pdev->dev, | 470 | ret = pdev->driver->sriov_configure(pdev, num_vfs); |
493 | "Invalid value for number of VFs to enable: %d\n", num_vfs); | 471 | if (ret < 0) |
472 | return ret; | ||
494 | 473 | ||
495 | return -EINVAL; | 474 | if (ret != num_vfs) |
475 | dev_warn(&pdev->dev, "%d VFs requested; only %d enabled\n", | ||
476 | num_vfs, ret); | ||
477 | |||
478 | return count; | ||
496 | } | 479 | } |
497 | 480 | ||
498 | static struct device_attribute sriov_totalvfs_attr = __ATTR_RO(sriov_totalvfs); | 481 | static struct device_attribute sriov_totalvfs_attr = __ATTR_RO(sriov_totalvfs); |
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index d4824cb78b4..08c243ab034 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
@@ -134,10 +134,28 @@ static int pcie_port_runtime_resume(struct device *dev) | |||
134 | return 0; | 134 | return 0; |
135 | } | 135 | } |
136 | 136 | ||
137 | static int pci_dev_pme_poll(struct pci_dev *pdev, void *data) | ||
138 | { | ||
139 | bool *pme_poll = data; | ||
140 | |||
141 | if (pdev->pme_poll) | ||
142 | *pme_poll = true; | ||
143 | return 0; | ||
144 | } | ||
145 | |||
137 | static int pcie_port_runtime_idle(struct device *dev) | 146 | static int pcie_port_runtime_idle(struct device *dev) |
138 | { | 147 | { |
148 | struct pci_dev *pdev = to_pci_dev(dev); | ||
149 | bool pme_poll = false; | ||
150 | |||
151 | /* | ||
152 | * If any subordinate device needs pme poll, we should keep | ||
153 | * the port in D0, because we need port in D0 to poll it. | ||
154 | */ | ||
155 | pci_walk_bus(pdev->subordinate, pci_dev_pme_poll, &pme_poll); | ||
139 | /* Delay for a short while to prevent too frequent suspend/resume */ | 156 | /* Delay for a short while to prevent too frequent suspend/resume */ |
140 | pm_schedule_suspend(dev, 10); | 157 | if (!pme_poll) |
158 | pm_schedule_suspend(dev, 10); | ||
141 | return -EBUSY; | 159 | return -EBUSY; |
142 | } | 160 | } |
143 | #else | 161 | #else |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 8f7a6344e79..0369fb6fc1d 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -2725,7 +2725,7 @@ static void ricoh_mmc_fixup_r5c832(struct pci_dev *dev) | |||
2725 | if (PCI_FUNC(dev->devfn)) | 2725 | if (PCI_FUNC(dev->devfn)) |
2726 | return; | 2726 | return; |
2727 | /* | 2727 | /* |
2728 | * RICOH 0xe823 SD/MMC card reader fails to recognize | 2728 | * RICOH 0xe822 and 0xe823 SD/MMC card readers fail to recognize |
2729 | * certain types of SD/MMC cards. Lowering the SD base | 2729 | * certain types of SD/MMC cards. Lowering the SD base |
2730 | * clock frequency from 200Mhz to 50Mhz fixes this issue. | 2730 | * clock frequency from 200Mhz to 50Mhz fixes this issue. |
2731 | * | 2731 | * |
@@ -2736,7 +2736,8 @@ static void ricoh_mmc_fixup_r5c832(struct pci_dev *dev) | |||
2736 | * 0xf9 - Key register for 0x150 | 2736 | * 0xf9 - Key register for 0x150 |
2737 | * 0xfc - key register for 0xe1 | 2737 | * 0xfc - key register for 0xe1 |
2738 | */ | 2738 | */ |
2739 | if (dev->device == PCI_DEVICE_ID_RICOH_R5CE823) { | 2739 | if (dev->device == PCI_DEVICE_ID_RICOH_R5CE822 || |
2740 | dev->device == PCI_DEVICE_ID_RICOH_R5CE823) { | ||
2740 | pci_write_config_byte(dev, 0xf9, 0xfc); | 2741 | pci_write_config_byte(dev, 0xf9, 0xfc); |
2741 | pci_write_config_byte(dev, 0x150, 0x10); | 2742 | pci_write_config_byte(dev, 0x150, 0x10); |
2742 | pci_write_config_byte(dev, 0xf9, 0x00); | 2743 | pci_write_config_byte(dev, 0xf9, 0x00); |
@@ -2763,6 +2764,8 @@ static void ricoh_mmc_fixup_r5c832(struct pci_dev *dev) | |||
2763 | } | 2764 | } |
2764 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); | 2765 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); |
2765 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); | 2766 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); |
2767 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5CE822, ricoh_mmc_fixup_r5c832); | ||
2768 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5CE822, ricoh_mmc_fixup_r5c832); | ||
2766 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5CE823, ricoh_mmc_fixup_r5c832); | 2769 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5CE823, ricoh_mmc_fixup_r5c832); |
2767 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5CE823, ricoh_mmc_fixup_r5c832); | 2770 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5CE823, ricoh_mmc_fixup_r5c832); |
2768 | #endif /*CONFIG_MMC_RICOH_MMC*/ | 2771 | #endif /*CONFIG_MMC_RICOH_MMC*/ |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 0f8447376dd..0eb65796bcb 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
@@ -1568,6 +1568,7 @@ | |||
1568 | #define PCI_DEVICE_ID_RICOH_RL5C476 0x0476 | 1568 | #define PCI_DEVICE_ID_RICOH_RL5C476 0x0476 |
1569 | #define PCI_DEVICE_ID_RICOH_RL5C478 0x0478 | 1569 | #define PCI_DEVICE_ID_RICOH_RL5C478 0x0478 |
1570 | #define PCI_DEVICE_ID_RICOH_R5C822 0x0822 | 1570 | #define PCI_DEVICE_ID_RICOH_R5C822 0x0822 |
1571 | #define PCI_DEVICE_ID_RICOH_R5CE822 0xe822 | ||
1571 | #define PCI_DEVICE_ID_RICOH_R5CE823 0xe823 | 1572 | #define PCI_DEVICE_ID_RICOH_R5CE823 0xe823 |
1572 | #define PCI_DEVICE_ID_RICOH_R5C832 0x0832 | 1573 | #define PCI_DEVICE_ID_RICOH_R5C832 0x0832 |
1573 | #define PCI_DEVICE_ID_RICOH_R5C843 0x0843 | 1574 | #define PCI_DEVICE_ID_RICOH_R5C843 0x0843 |
diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h index 6b7b6f1e2fd..ebfadc56d1b 100644 --- a/include/uapi/linux/pci_regs.h +++ b/include/uapi/linux/pci_regs.h | |||
@@ -458,6 +458,8 @@ | |||
458 | #define PCI_EXP_DEVSTA_TRPND 0x20 /* Transactions Pending */ | 458 | #define PCI_EXP_DEVSTA_TRPND 0x20 /* Transactions Pending */ |
459 | #define PCI_EXP_LNKCAP 12 /* Link Capabilities */ | 459 | #define PCI_EXP_LNKCAP 12 /* Link Capabilities */ |
460 | #define PCI_EXP_LNKCAP_SLS 0x0000000f /* Supported Link Speeds */ | 460 | #define PCI_EXP_LNKCAP_SLS 0x0000000f /* Supported Link Speeds */ |
461 | #define PCI_EXP_LNKCAP_SLS_2_5GB 0x1 /* LNKCAP2 SLS Vector bit 0 (2.5GT/s) */ | ||
462 | #define PCI_EXP_LNKCAP_SLS_5_0GB 0x2 /* LNKCAP2 SLS Vector bit 1 (5.0GT/s) */ | ||
461 | #define PCI_EXP_LNKCAP_MLW 0x000003f0 /* Maximum Link Width */ | 463 | #define PCI_EXP_LNKCAP_MLW 0x000003f0 /* Maximum Link Width */ |
462 | #define PCI_EXP_LNKCAP_ASPMS 0x00000c00 /* ASPM Support */ | 464 | #define PCI_EXP_LNKCAP_ASPMS 0x00000c00 /* ASPM Support */ |
463 | #define PCI_EXP_LNKCAP_L0SEL 0x00007000 /* L0s Exit Latency */ | 465 | #define PCI_EXP_LNKCAP_L0SEL 0x00007000 /* L0s Exit Latency */ |