mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-27 14:14:24 +08:00
Merge branch 'pci/pm'
- Protect driver's D3cold preference from being overwritten by user space via sysfs (Lukas Wunner) - Avoid PME from D3hot/D3cold for AMD Rembrandt and Phoenix USB4 to fix wakeup by USB4-attached devices (Mario Limonciello) * pci/pm: x86/PCI: Avoid PME from D3hot/D3cold for AMD Rembrandt and Phoenix USB4 PCI/sysfs: Protect driver's D3cold preference from user space
This commit is contained in:
commit
2afbbc65be
@ -3,9 +3,11 @@
|
||||
* Exceptions for specific devices. Usually work-arounds for fatal design flaws.
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <linux/vgaarb.h>
|
||||
#include <asm/amd_nb.h>
|
||||
#include <asm/hpet.h>
|
||||
@ -904,3 +906,60 @@ static void chromeos_fixup_apl_pci_l1ss_capability(struct pci_dev *dev)
|
||||
}
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x5ad6, chromeos_save_apl_pci_l1ss_capability);
|
||||
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, 0x5ad6, chromeos_fixup_apl_pci_l1ss_capability);
|
||||
|
||||
#ifdef CONFIG_SUSPEND
|
||||
/*
|
||||
* Root Ports on some AMD SoCs advertise PME_Support for D3hot and D3cold, but
|
||||
* if the SoC is put into a hardware sleep state by the amd-pmc driver, the
|
||||
* Root Ports don't generate wakeup interrupts for USB devices.
|
||||
*
|
||||
* When suspending, remove D3hot and D3cold from the PME_Support advertised
|
||||
* by the Root Port so we don't use those states if we're expecting wakeup
|
||||
* interrupts. Restore the advertised PME_Support when resuming.
|
||||
*/
|
||||
static void amd_rp_pme_suspend(struct pci_dev *dev)
|
||||
{
|
||||
struct pci_dev *rp;
|
||||
|
||||
/*
|
||||
* PM_SUSPEND_ON means we're doing runtime suspend, which means
|
||||
* amd-pmc will not be involved so PMEs during D3 work as advertised.
|
||||
*
|
||||
* The PMEs *do* work if amd-pmc doesn't put the SoC in the hardware
|
||||
* sleep state, but we assume amd-pmc is always present.
|
||||
*/
|
||||
if (pm_suspend_target_state == PM_SUSPEND_ON)
|
||||
return;
|
||||
|
||||
rp = pcie_find_root_port(dev);
|
||||
if (!rp->pm_cap)
|
||||
return;
|
||||
|
||||
rp->pme_support &= ~((PCI_PM_CAP_PME_D3hot|PCI_PM_CAP_PME_D3cold) >>
|
||||
PCI_PM_CAP_PME_SHIFT);
|
||||
dev_info_once(&rp->dev, "quirk: disabling D3cold for suspend\n");
|
||||
}
|
||||
|
||||
static void amd_rp_pme_resume(struct pci_dev *dev)
|
||||
{
|
||||
struct pci_dev *rp;
|
||||
u16 pmc;
|
||||
|
||||
rp = pcie_find_root_port(dev);
|
||||
if (!rp->pm_cap)
|
||||
return;
|
||||
|
||||
pci_read_config_word(rp, rp->pm_cap + PCI_PM_PMC, &pmc);
|
||||
rp->pme_support = FIELD_GET(PCI_PM_CAP_PME_MASK, pmc);
|
||||
}
|
||||
/* Rembrandt (yellow_carp) */
|
||||
DECLARE_PCI_FIXUP_SUSPEND(PCI_VENDOR_ID_AMD, 0x162e, amd_rp_pme_suspend);
|
||||
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x162e, amd_rp_pme_resume);
|
||||
DECLARE_PCI_FIXUP_SUSPEND(PCI_VENDOR_ID_AMD, 0x162f, amd_rp_pme_suspend);
|
||||
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x162f, amd_rp_pme_resume);
|
||||
/* Phoenix (pink_sardine) */
|
||||
DECLARE_PCI_FIXUP_SUSPEND(PCI_VENDOR_ID_AMD, 0x1668, amd_rp_pme_suspend);
|
||||
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x1668, amd_rp_pme_resume);
|
||||
DECLARE_PCI_FIXUP_SUSPEND(PCI_VENDOR_ID_AMD, 0x1669, amd_rp_pme_suspend);
|
||||
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, 0x1669, amd_rp_pme_resume);
|
||||
#endif /* CONFIG_SUSPEND */
|
||||
|
@ -911,7 +911,7 @@ pci_power_t acpi_pci_choose_state(struct pci_dev *pdev)
|
||||
{
|
||||
int acpi_state, d_max;
|
||||
|
||||
if (pdev->no_d3cold)
|
||||
if (pdev->no_d3cold || !pdev->d3cold_allowed)
|
||||
d_max = ACPI_STATE_D3_HOT;
|
||||
else
|
||||
d_max = ACPI_STATE_D3_COLD;
|
||||
|
@ -530,10 +530,7 @@ static ssize_t d3cold_allowed_store(struct device *dev,
|
||||
return -EINVAL;
|
||||
|
||||
pdev->d3cold_allowed = !!val;
|
||||
if (pdev->d3cold_allowed)
|
||||
pci_d3cold_enable(pdev);
|
||||
else
|
||||
pci_d3cold_disable(pdev);
|
||||
pci_bridge_d3_update(pdev);
|
||||
|
||||
pm_runtime_resume(dev);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user