diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/acpi/sleep.c | 4 | ||||
-rw-r--r-- | drivers/firmware/dmi_scan.c | 20 | ||||
-rw-r--r-- | drivers/pci/pci.c | 6 | ||||
-rw-r--r-- | drivers/pci/probe.c | 22 |
4 files changed, 41 insertions, 11 deletions
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 46cde0912762..b35923e3a926 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -376,12 +376,10 @@ void __init acpi_sleep_no_blacklist(void) static void __init acpi_sleep_dmi_check(void) { - int year; - if (ignore_blacklist) return; - if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && year >= 2012) + if (dmi_get_bios_year() >= 2012) acpi_nvs_nosave_s3(); dmi_check_system(acpisleep_dmi_table); diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index e763e1484331..e35c5e04c46a 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c @@ -1005,6 +1005,26 @@ out: EXPORT_SYMBOL(dmi_get_date); /** + * dmi_get_bios_year - get a year out of DMI_BIOS_DATE field + * + * Returns year on success, -ENXIO if DMI is not selected, + * or a different negative error code if DMI field is not present + * or not parseable. + */ +int dmi_get_bios_year(void) +{ + bool exists; + int year; + + exists = dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL); + if (!exists) + return -ENODATA; + + return year ? year : -ERANGE; +} +EXPORT_SYMBOL(dmi_get_bios_year); + +/** * dmi_walk - Walk the DMI table and get called back for every record * @decode: Callback function * @private_data: Private data to be passed to the callback function diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index bd6f156dc3cf..99ec0ef5ba82 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -2258,8 +2258,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; @@ -2287,10 +2285,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 ef5377438a1e..3c365dc996e7 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" @@ -2518,14 +2519,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); |