Commit 13a84687 authored by Bjorn Helgaas's avatar Bjorn Helgaas

Merge branch 'pci/misc' into next

* pci/misc:
  PCI/PM: Add comments for PME poll support for PCIe
  PCI: Add PLX PCI 9050 workaround for some Meilhaus DAQ cards
  PCI: Add workaround for PLX PCI 9050 BAR alignment erratum
  PCI: Convert dev_printk(KERN_<LEVEL> to dev_<level>(
  x86/PCI: Ignore _SEG on HP xw9300
  PCI: Don't touch card regs after runtime suspend D3
parents 8f0d8163 6e965e0d
...@@ -22,6 +22,7 @@ struct pci_root_info { ...@@ -22,6 +22,7 @@ struct pci_root_info {
}; };
static bool pci_use_crs = true; static bool pci_use_crs = true;
static bool pci_ignore_seg = false;
static int __init set_use_crs(const struct dmi_system_id *id) static int __init set_use_crs(const struct dmi_system_id *id)
{ {
...@@ -35,7 +36,14 @@ static int __init set_nouse_crs(const struct dmi_system_id *id) ...@@ -35,7 +36,14 @@ static int __init set_nouse_crs(const struct dmi_system_id *id)
return 0; return 0;
} }
static const struct dmi_system_id pci_use_crs_table[] __initconst = { static int __init set_ignore_seg(const struct dmi_system_id *id)
{
printk(KERN_INFO "PCI: %s detected: ignoring ACPI _SEG\n", id->ident);
pci_ignore_seg = true;
return 0;
}
static const struct dmi_system_id pci_crs_quirks[] __initconst = {
/* http://bugzilla.kernel.org/show_bug.cgi?id=14183 */ /* http://bugzilla.kernel.org/show_bug.cgi?id=14183 */
{ {
.callback = set_use_crs, .callback = set_use_crs,
...@@ -98,6 +106,16 @@ static const struct dmi_system_id pci_use_crs_table[] __initconst = { ...@@ -98,6 +106,16 @@ static const struct dmi_system_id pci_use_crs_table[] __initconst = {
DMI_MATCH(DMI_BIOS_VERSION, "6JET85WW (1.43 )"), DMI_MATCH(DMI_BIOS_VERSION, "6JET85WW (1.43 )"),
}, },
}, },
/* https://bugzilla.kernel.org/show_bug.cgi?id=15362 */
{
.callback = set_ignore_seg,
.ident = "HP xw9300",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
DMI_MATCH(DMI_PRODUCT_NAME, "HP xw9300 Workstation"),
},
},
{} {}
}; };
...@@ -108,7 +126,7 @@ void __init pci_acpi_crs_quirks(void) ...@@ -108,7 +126,7 @@ void __init pci_acpi_crs_quirks(void)
if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && year < 2008) if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && year < 2008)
pci_use_crs = false; pci_use_crs = false;
dmi_check_system(pci_use_crs_table); dmi_check_system(pci_crs_quirks);
/* /*
* If the user specifies "pci=use_crs" or "pci=nocrs" explicitly, that * If the user specifies "pci=use_crs" or "pci=nocrs" explicitly, that
...@@ -455,6 +473,9 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) ...@@ -455,6 +473,9 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root)
int pxm; int pxm;
#endif #endif
if (pci_ignore_seg)
domain = 0;
if (domain && !pci_domains_supported) { if (domain && !pci_domains_supported) {
printk(KERN_WARNING "pci_bus %04x:%02x: " printk(KERN_WARNING "pci_bus %04x:%02x: "
"ignored (multiple domains not supported)\n", "ignored (multiple domains not supported)\n",
......
...@@ -14,11 +14,11 @@ static void pci_note_irq_problem(struct pci_dev *pdev, const char *reason) ...@@ -14,11 +14,11 @@ static void pci_note_irq_problem(struct pci_dev *pdev, const char *reason)
{ {
struct pci_dev *parent = to_pci_dev(pdev->dev.parent); struct pci_dev *parent = to_pci_dev(pdev->dev.parent);
dev_printk(KERN_ERR, &pdev->dev, dev_err(&pdev->dev,
"Potentially misrouted IRQ (Bridge %s %04x:%04x)\n", "Potentially misrouted IRQ (Bridge %s %04x:%04x)\n",
dev_name(&parent->dev), parent->vendor, parent->device); dev_name(&parent->dev), parent->vendor, parent->device);
dev_printk(KERN_ERR, &pdev->dev, "%s\n", reason); dev_err(&pdev->dev, "%s\n", reason);
dev_printk(KERN_ERR, &pdev->dev, "Please report to linux-kernel@vger.kernel.org\n"); dev_err(&pdev->dev, "Please report to linux-kernel@vger.kernel.org\n");
WARN_ON(1); WARN_ON(1);
} }
......
...@@ -1023,10 +1023,10 @@ static int pci_pm_runtime_suspend(struct device *dev) ...@@ -1023,10 +1023,10 @@ static int pci_pm_runtime_suspend(struct device *dev)
return 0; return 0;
} }
if (!pci_dev->state_saved) if (!pci_dev->state_saved) {
pci_save_state(pci_dev); pci_save_state(pci_dev);
pci_finish_runtime_suspend(pci_dev);
pci_finish_runtime_suspend(pci_dev); }
return 0; return 0;
} }
......
...@@ -28,7 +28,7 @@ MODULE_PARM_DESC(ids, "Initial PCI IDs to add to the stub driver, format is " ...@@ -28,7 +28,7 @@ MODULE_PARM_DESC(ids, "Initial PCI IDs to add to the stub driver, format is "
static int pci_stub_probe(struct pci_dev *dev, const struct pci_device_id *id) static int pci_stub_probe(struct pci_dev *dev, const struct pci_device_id *id)
{ {
dev_printk(KERN_INFO, &dev->dev, "claimed by stub\n"); dev_info(&dev->dev, "claimed by stub\n");
return 0; return 0;
} }
......
...@@ -1578,15 +1578,25 @@ void pci_pme_active(struct pci_dev *dev, bool enable) ...@@ -1578,15 +1578,25 @@ void pci_pme_active(struct pci_dev *dev, bool enable)
pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr); pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr);
/* PCI (as opposed to PCIe) PME requires that the device have /*
its PME# line hooked up correctly. Not all hardware vendors * PCI (as opposed to PCIe) PME requires that the device have
do this, so the PME never gets delivered and the device * its PME# line hooked up correctly. Not all hardware vendors
remains asleep. The easiest way around this is to * do this, so the PME never gets delivered and the device
periodically walk the list of suspended devices and check * remains asleep. The easiest way around this is to
whether any have their PME flag set. The assumption is that * periodically walk the list of suspended devices and check
we'll wake up often enough anyway that this won't be a huge * whether any have their PME flag set. The assumption is that
hit, and the power savings from the devices will still be a * we'll wake up often enough anyway that this won't be a huge
win. */ * hit, and the power savings from the devices will still be a
* win.
*
* Although PCIe uses in-band PME message instead of PME# line
* to report PME, PME does not work for some PCIe devices in
* reality. For example, there are devices that set their PME
* status bits, but don't really bother to send a PME message;
* there are PCI Express Root Ports that don't bother to
* trigger interrupts when they receive PME messages from the
* devices below. So PME poll is used for PCIe devices too.
*/
if (dev->pme_poll) { if (dev->pme_poll) {
struct pci_pme_device *pme_dev; struct pci_pme_device *pme_dev;
......
...@@ -242,8 +242,7 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link) ...@@ -242,8 +242,7 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link)
return; return;
/* Training failed. Restore common clock configurations */ /* Training failed. Restore common clock configurations */
dev_printk(KERN_ERR, &parent->dev, dev_err(&parent->dev, "ASPM: Could not configure common clock\n");
"ASPM: Could not configure common clock\n");
list_for_each_entry(child, &linkbus->devices, bus_list) list_for_each_entry(child, &linkbus->devices, bus_list)
pcie_capability_write_word(child, PCI_EXP_LNKCTL, pcie_capability_write_word(child, PCI_EXP_LNKCTL,
child_reg[PCI_FUNC(child->devfn)]); child_reg[PCI_FUNC(child->devfn)]);
...@@ -507,9 +506,7 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev) ...@@ -507,9 +506,7 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev)
*/ */
pcie_capability_read_dword(child, PCI_EXP_DEVCAP, &reg32); pcie_capability_read_dword(child, PCI_EXP_DEVCAP, &reg32);
if (!(reg32 & PCI_EXP_DEVCAP_RBER) && !aspm_force) { if (!(reg32 & PCI_EXP_DEVCAP_RBER) && !aspm_force) {
dev_printk(KERN_INFO, &child->dev, "disabling ASPM" dev_info(&child->dev, "disabling ASPM on pre-1.1 PCIe device. You can enable it with 'pcie_aspm=force'\n");
" on pre-1.1 PCIe device. You can enable it"
" with 'pcie_aspm=force'\n");
return -EINVAL; return -EINVAL;
} }
} }
......
...@@ -1790,6 +1790,45 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TOSHIBA_2, ...@@ -1790,6 +1790,45 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TOSHIBA_2,
PCI_DEVICE_ID_TOSHIBA_TC86C001_IDE, PCI_DEVICE_ID_TOSHIBA_TC86C001_IDE,
quirk_tc86c001_ide); quirk_tc86c001_ide);
/*
* PLX PCI 9050 PCI Target bridge controller has an errata that prevents the
* local configuration registers accessible via BAR0 (memory) or BAR1 (i/o)
* being read correctly if bit 7 of the base address is set.
* The BAR0 or BAR1 region may be disabled (size 0) or enabled (size 128).
* Re-allocate the regions to a 256-byte boundary if necessary.
*/
static void __devinit quirk_plx_pci9050(struct pci_dev *dev)
{
unsigned int bar;
/* Fixed in revision 2 (PCI 9052). */
if (dev->revision >= 2)
return;
for (bar = 0; bar <= 1; bar++)
if (pci_resource_len(dev, bar) == 0x80 &&
(pci_resource_start(dev, bar) & 0x80)) {
struct resource *r = &dev->resource[bar];
dev_info(&dev->dev,
"Re-allocating PLX PCI 9050 BAR %u to length 256 to avoid bit 7 bug\n",
bar);
r->start = 0;
r->end = 0xff;
}
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
quirk_plx_pci9050);
/*
* The following Meilhaus (vendor ID 0x1402) device IDs (amongst others)
* may be using the PLX PCI 9050: 0x0630, 0x0940, 0x0950, 0x0960, 0x100b,
* 0x1400, 0x140a, 0x140b, 0x14e0, 0x14ea, 0x14eb, 0x1604, 0x1608, 0x160c,
* 0x168f, 0x2000, 0x2600, 0x3000, 0x810a, 0x810b.
*
* Currently, device IDs 0x2000 and 0x2600 are used by the Comedi "me_daq"
* driver.
*/
DECLARE_PCI_FIXUP_HEADER(0x1402, 0x2000, quirk_plx_pci9050);
DECLARE_PCI_FIXUP_HEADER(0x1402, 0x2600, quirk_plx_pci9050);
static void __devinit quirk_netmos(struct pci_dev *dev) static void __devinit quirk_netmos(struct pci_dev *dev)
{ {
unsigned int num_parallel = (dev->subsystem_device & 0xf0) >> 4; unsigned int num_parallel = (dev->subsystem_device & 0xf0) >> 4;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment