]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - drivers/pci/pci-acpi.c
Revert "UBUNTU: SAUCE: pci/nvme: prevent WDC PC SN720 NVMe from entering D3 and being...
[mirror_ubuntu-bionic-kernel.git] / drivers / pci / pci-acpi.c
index 4708eb9df71b0ebb7548b87e4cb4238a0b900b6a..67c4bbd73bc278513f11272fdf63e8620b1eeee3 100644 (file)
@@ -598,6 +598,18 @@ static bool acpi_pci_need_resume(struct pci_dev *dev)
 {
        struct acpi_device *adev = ACPI_COMPANION(&dev->dev);
 
+       /*
+        * In some cases (eg. Samsung 305V4A) leaving a bridge in suspend over
+        * system-wide suspend/resume confuses the platform firmware, so avoid
+        * doing that, unless the bridge has a driver that should take care of
+        * the PM handling.  According to Section 16.1.6 of ACPI 6.2, endpoint
+        * devices are expected to be in D3 before invoking the S3 entry path
+        * from the firmware, so they should not be affected by this issue.
+        */
+       if (pci_is_bridge(dev) && !dev->driver &&
+           acpi_target_system_state() != ACPI_STATE_S0)
+               return true;
+
        if (!adev || !acpi_device_power_manageable(adev))
                return false;
 
@@ -723,6 +735,24 @@ static void pci_acpi_optimize_delay(struct pci_dev *pdev,
        ACPI_FREE(obj);
 }
 
+static void pci_acpi_set_untrusted(struct pci_dev *dev)
+{
+       u8 val;
+
+       if (pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT)
+               return;
+       if (device_property_read_u8(&dev->dev, "ExternalFacingPort", &val))
+               return;
+
+       /*
+        * These root ports expose PCIe (including DMA) outside of the
+        * system so make sure we treat them and everything behind as
+        * untrusted.
+        */
+       if (val)
+               dev->untrusted = 1;
+}
+
 static void pci_acpi_setup(struct device *dev)
 {
        struct pci_dev *pci_dev = to_pci_dev(dev);
@@ -732,6 +762,7 @@ static void pci_acpi_setup(struct device *dev)
                return;
 
        pci_acpi_optimize_delay(pci_dev, adev->handle);
+       pci_acpi_set_untrusted(pci_dev);
 
        pci_acpi_add_pm_notifier(adev, pci_dev);
        if (!adev->wakeup.flags.valid)