summaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/dwc/pcie-designware-host.c2
-rw-r--r--drivers/pci/pci-driver.c17
-rw-r--r--drivers/pci/pci.c14
-rw-r--r--drivers/pci/probe.c22
-rw-r--r--drivers/pci/quirks.c60
-rw-r--r--drivers/pci/setup-res.c4
-rw-r--r--drivers/pci/vpd.c37
7 files changed, 104 insertions, 52 deletions
diff --git a/drivers/pci/dwc/pcie-designware-host.c b/drivers/pci/dwc/pcie-designware-host.c
index 550fdbb5c226..6c409079d514 100644
--- a/drivers/pci/dwc/pcie-designware-host.c
+++ b/drivers/pci/dwc/pcie-designware-host.c
@@ -667,7 +667,7 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
/* setup bus numbers */
val = dw_pcie_readl_dbi(pci, PCI_PRIMARY_BUS);
val &= 0xff000000;
- val |= 0x00010100;
+ val |= 0x00ff0100;
dw_pcie_writel_dbi(pci, PCI_PRIMARY_BUS, val);
/* setup command register */
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 28cf87a7ff4c..6ace47099fc5 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -1237,11 +1237,14 @@ static int pci_pm_runtime_suspend(struct device *dev)
int error;
/*
- * If pci_dev->driver is not set (unbound), the device should
- * always remain in D0 regardless of the runtime PM status
+ * If pci_dev->driver is not set (unbound), we leave the device in D0,
+ * but it may go to D3cold when the bridge above it runtime suspends.
+ * Save its config space in case that happens.
*/
- if (!pci_dev->driver)
+ if (!pci_dev->driver) {
+ pci_save_state(pci_dev);
return 0;
+ }
if (!pm || !pm->runtime_suspend)
return -ENOSYS;
@@ -1289,16 +1292,18 @@ static int pci_pm_runtime_resume(struct device *dev)
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
/*
- * If pci_dev->driver is not set (unbound), the device should
- * always remain in D0 regardless of the runtime PM status
+ * Restoring config space is necessary even if the device is not bound
+ * to a driver because although we left it in D0, it may have gone to
+ * D3cold when the bridge above it runtime suspended.
*/
+ pci_restore_standard_config(pci_dev);
+
if (!pci_dev->driver)
return 0;
if (!pm || !pm->runtime_resume)
return -ENOSYS;
- pci_restore_standard_config(pci_dev);
pci_fixup_device(pci_fixup_resume_early, pci_dev);
pci_enable_wake(pci_dev, PCI_D0, false);
pci_fixup_device(pci_fixup_resume, pci_dev);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 43aeecc4b675..aa86e904f93c 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -804,7 +804,7 @@ static int pci_wakeup(struct pci_dev *pci_dev, void *ign)
* pci_wakeup_bus - Walk given bus and wake up devices on it
* @bus: Top bus of the subtree to walk.
*/
-static void pci_wakeup_bus(struct pci_bus *bus)
+void pci_wakeup_bus(struct pci_bus *bus)
{
if (bus)
pci_walk_bus(bus, pci_wakeup, NULL);
@@ -854,11 +854,11 @@ static int __pci_dev_set_current_state(struct pci_dev *dev, void *data)
}
/**
- * __pci_bus_set_current_state - Walk given bus and set current state of devices
+ * pci_bus_set_current_state - Walk given bus and set current state of devices
* @bus: Top bus of the subtree to walk.
* @state: state to be set
*/
-static void __pci_bus_set_current_state(struct pci_bus *bus, pci_power_t state)
+void pci_bus_set_current_state(struct pci_bus *bus, pci_power_t state)
{
if (bus)
pci_walk_bus(bus, __pci_dev_set_current_state, &state);
@@ -880,7 +880,7 @@ int __pci_complete_power_transition(struct pci_dev *dev, pci_power_t state)
ret = pci_platform_power_transition(dev, state);
/* Power off the bridge may power off the whole hierarchy */
if (!ret && state == PCI_D3cold)
- __pci_bus_set_current_state(dev->subordinate, PCI_D3cold);
+ pci_bus_set_current_state(dev->subordinate, PCI_D3cold);
return ret;
}
EXPORT_SYMBOL_GPL(__pci_complete_power_transition);
@@ -2271,8 +2271,6 @@ void pci_config_pm_runtime_put(struct pci_dev *pdev)
*/
bool pci_bridge_d3_possible(struct pci_dev *bridge)
{
- unsigned int year;
-
if (!pci_is_pcie(bridge))
return false;
@@ -2300,10 +2298,8 @@ bool pci_bridge_d3_possible(struct pci_dev *bridge)
* It should be safe to put PCIe ports from 2015 or newer
* to D3.
*/
- if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) &&
- year >= 2015) {
+ if (dmi_get_bios_year() >= 2015)
return true;
- }
break;
}
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index caa07109e5f5..ac91b6fd0bcd 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -16,6 +16,7 @@
#include <linux/pci-aspm.h>
#include <linux/aer.h>
#include <linux/acpi.h>
+#include <linux/hypervisor.h>
#include <linux/irqdomain.h>
#include <linux/pm_runtime.h>
#include "pci.h"
@@ -2579,14 +2580,29 @@ static unsigned int pci_scan_child_bus_extend(struct pci_bus *bus,
{
unsigned int used_buses, normal_bridges = 0, hotplug_bridges = 0;
unsigned int start = bus->busn_res.start;
- unsigned int devfn, cmax, max = start;
+ unsigned int devfn, fn, cmax, max = start;
struct pci_dev *dev;
+ int nr_devs;
dev_dbg(&bus->dev, "scanning bus\n");
/* Go find them, Rover! */
- for (devfn = 0; devfn < 0x100; devfn += 8)
- pci_scan_slot(bus, devfn);
+ for (devfn = 0; devfn < 256; devfn += 8) {
+ nr_devs = pci_scan_slot(bus, devfn);
+
+ /*
+ * The Jailhouse hypervisor may pass individual functions of a
+ * multi-function device to a guest without passing function 0.
+ * Look for them as well.
+ */
+ if (jailhouse_paravirt() && nr_devs == 0) {
+ for (fn = 1; fn < 8; fn++) {
+ dev = pci_scan_single_device(bus, devfn + fn);
+ if (dev)
+ dev->multifunction = 1;
+ }
+ }
+ }
/* Reserve buses for SR-IOV capability */
used_buses = pci_iov_bus_range(bus);
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 76eaf4ad7652..26141b1946ee 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -26,6 +26,7 @@
#include <linux/ktime.h>
#include <linux/mm.h>
#include <linux/platform_data/x86/apple.h>
+#include <linux/pm_runtime.h>
#include <asm/dma.h> /* isa_dma_bridge_buggy */
#include "pci.h"
@@ -2217,25 +2218,6 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82865_HB,
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82875_HB,
quirk_unhide_mch_dev6);
-#ifdef CONFIG_TILEPRO
-/*
- * The Tilera TILEmpower tilepro platform needs to set the link speed
- * to 2.5GT(Giga-Transfers)/s (Gen 1). The default link speed
- * setting is 5GT/s (Gen 2). 0x98 is the Link Control2 PCIe
- * capability register of the PEX8624 PCIe switch. The switch
- * supports link speed auto negotiation, but falsely sets
- * the link speed to 5GT/s.
- */
-static void quirk_tile_plx_gen1(struct pci_dev *dev)
-{
- if (tile_plx_gen1) {
- pci_write_config_dword(dev, 0x98, 0x1);
- mdelay(50);
- }
-}
-DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8624, quirk_tile_plx_gen1);
-#endif /* CONFIG_TILEPRO */
-
#ifdef CONFIG_PCI_MSI
/* Some chipsets do not support MSI. We cannot easily rely on setting
* PCI_BUS_FLAGS_NO_MSI in its bus flags because there are actually
@@ -3775,6 +3757,8 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9230,
quirk_dma_func1_alias);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TTI, 0x0642,
quirk_dma_func1_alias);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TTI, 0x0645,
+ quirk_dma_func1_alias);
/* https://bugs.gentoo.org/show_bug.cgi?id=497630 */
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_JMICRON,
PCI_DEVICE_ID_JMICRON_JMB388_ESD,
@@ -4715,3 +4699,41 @@ static void quirk_fsl_no_msi(struct pci_dev *pdev)
pdev->no_msi = 1;
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, quirk_fsl_no_msi);
+
+/*
+ * GPUs with integrated HDA controller for streaming audio to attached displays
+ * need a device link from the HDA controller (consumer) to the GPU (supplier)
+ * so that the GPU is powered up whenever the HDA controller is accessed.
+ * The GPU and HDA controller are functions 0 and 1 of the same PCI device.
+ * The device link stays in place until shutdown (or removal of the PCI device
+ * if it's hotplugged). Runtime PM is allowed by default on the HDA controller
+ * to prevent it from permanently keeping the GPU awake.
+ */
+static void quirk_gpu_hda(struct pci_dev *hda)
+{
+ struct pci_dev *gpu;
+
+ if (PCI_FUNC(hda->devfn) != 1)
+ return;
+
+ gpu = pci_get_domain_bus_and_slot(pci_domain_nr(hda->bus),
+ hda->bus->number,
+ PCI_DEVFN(PCI_SLOT(hda->devfn), 0));
+ if (!gpu || (gpu->class >> 16) != PCI_BASE_CLASS_DISPLAY) {
+ pci_dev_put(gpu);
+ return;
+ }
+
+ if (!device_link_add(&hda->dev, &gpu->dev,
+ DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME))
+ pci_err(hda, "cannot link HDA to GPU %s\n", pci_name(gpu));
+
+ pm_runtime_allow(&hda->dev);
+ pci_dev_put(gpu);
+}
+DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_ATI, PCI_ANY_ID,
+ PCI_CLASS_MULTIMEDIA_HD_AUDIO, 8, quirk_gpu_hda);
+DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_AMD, PCI_ANY_ID,
+ PCI_CLASS_MULTIMEDIA_HD_AUDIO, 8, quirk_gpu_hda);
+DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
+ PCI_CLASS_MULTIMEDIA_HD_AUDIO, 8, quirk_gpu_hda);
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index 1ef01d79b52e..0cd83a4bd4c8 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -397,6 +397,10 @@ void pci_release_resource(struct pci_dev *dev, int resno)
struct resource *res = dev->resource + resno;
pci_info(dev, "BAR %d: releasing %pR\n", resno, res);
+
+ if (!res->parent)
+ return;
+
release_resource(res);
res->end = resource_size(res) - 1;
res->start = 0;
diff --git a/drivers/pci/vpd.c b/drivers/pci/vpd.c
index 00b8b5d37056..8617565ba561 100644
--- a/drivers/pci/vpd.c
+++ b/drivers/pci/vpd.c
@@ -617,19 +617,28 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_BROADCOM,
static void quirk_chelsio_extend_vpd(struct pci_dev *dev)
{
- pci_set_vpd_size(dev, 8192);
+ int chip = (dev->device & 0xf000) >> 12;
+ int func = (dev->device & 0x0f00) >> 8;
+ int prod = (dev->device & 0x00ff) >> 0;
+
+ /*
+ * If this is a T3-based adapter, there's a 1KB VPD area at offset
+ * 0xc00 which contains the preferred VPD values. If this is a T4 or
+ * later based adapter, the special VPD is at offset 0x400 for the
+ * Physical Functions (the SR-IOV Virtual Functions have no VPD
+ * Capabilities). The PCI VPD Access core routines will normally
+ * compute the size of the VPD by parsing the VPD Data Structure at
+ * offset 0x000. This will result in silent failures when attempting
+ * to accesses these other VPD areas which are beyond those computed
+ * limits.
+ */
+ if (chip == 0x0 && prod >= 0x20)
+ pci_set_vpd_size(dev, 8192);
+ else if (chip >= 0x4 && func < 0x8)
+ pci_set_vpd_size(dev, 2048);
}
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x20, quirk_chelsio_extend_vpd);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x21, quirk_chelsio_extend_vpd);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x22, quirk_chelsio_extend_vpd);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x23, quirk_chelsio_extend_vpd);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x24, quirk_chelsio_extend_vpd);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x25, quirk_chelsio_extend_vpd);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x26, quirk_chelsio_extend_vpd);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x30, quirk_chelsio_extend_vpd);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x31, quirk_chelsio_extend_vpd);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x32, quirk_chelsio_extend_vpd);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x35, quirk_chelsio_extend_vpd);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x36, quirk_chelsio_extend_vpd);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, 0x37, quirk_chelsio_extend_vpd);
+
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CHELSIO, PCI_ANY_ID,
+ quirk_chelsio_extend_vpd);
+
#endif