platform/x86: amd-pmc: Move to later in the suspend process
The `OS_HINT` message is supposed to indicate that everything else
that is supposed to go into the deepest state has done so.
This assumption is invalid as:
1) The CPUs will still go in and out of the deepest state
2) Other devices may still run their `noirq` suspend routines
3) The LPS0 ACPI device will still run
To more closely mirror how this works on other operating systems,
move the `amd-pmc` suspend to the very last thing before the s2idle
loop via an lps0 callback.
Fixes: 8d89835b04
("PM: suspend: Do not pause cpuidle in the suspend-to-idle path")
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Link: https://lore.kernel.org/r/20220317141445.6498-2-mario.limonciello@amd.com
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
parent
20e1d6402a
commit
b1f66033cd
1 changed files with 15 additions and 15 deletions
|
@ -639,9 +639,9 @@ static int amd_pmc_verify_czn_rtc(struct amd_pmc_dev *pdev, u32 *arg)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __maybe_unused amd_pmc_suspend(struct device *dev)
|
static void amd_pmc_s2idle_prepare(void)
|
||||||
{
|
{
|
||||||
struct amd_pmc_dev *pdev = dev_get_drvdata(dev);
|
struct amd_pmc_dev *pdev = &pmc;
|
||||||
int rc;
|
int rc;
|
||||||
u8 msg;
|
u8 msg;
|
||||||
u32 arg = 1;
|
u32 arg = 1;
|
||||||
|
@ -658,7 +658,7 @@ static int __maybe_unused amd_pmc_suspend(struct device *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dump the IdleMask before we send hint to SMU */
|
/* Dump the IdleMask before we send hint to SMU */
|
||||||
amd_pmc_idlemask_read(pdev, dev, NULL);
|
amd_pmc_idlemask_read(pdev, pdev->dev, NULL);
|
||||||
msg = amd_pmc_get_os_hint(pdev);
|
msg = amd_pmc_get_os_hint(pdev);
|
||||||
rc = amd_pmc_send_cmd(pdev, arg, NULL, msg, 0);
|
rc = amd_pmc_send_cmd(pdev, arg, NULL, msg, 0);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
|
@ -672,18 +672,16 @@ static int __maybe_unused amd_pmc_suspend(struct device *dev)
|
||||||
dev_err(pdev->dev, "error writing to STB\n");
|
dev_err(pdev->dev, "error writing to STB\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
return 0;
|
|
||||||
fail:
|
fail:
|
||||||
if (pdev->cpu_id == AMD_CPU_ID_CZN)
|
if (pdev->cpu_id == AMD_CPU_ID_CZN)
|
||||||
cpu_latency_qos_update_request(&pdev->amd_pmc_pm_qos_req,
|
cpu_latency_qos_update_request(&pdev->amd_pmc_pm_qos_req,
|
||||||
PM_QOS_DEFAULT_VALUE);
|
PM_QOS_DEFAULT_VALUE);
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __maybe_unused amd_pmc_resume(struct device *dev)
|
static void amd_pmc_s2idle_restore(void)
|
||||||
{
|
{
|
||||||
struct amd_pmc_dev *pdev = dev_get_drvdata(dev);
|
struct amd_pmc_dev *pdev = &pmc;
|
||||||
int rc;
|
int rc;
|
||||||
u8 msg;
|
u8 msg;
|
||||||
|
|
||||||
|
@ -696,7 +694,7 @@ static int __maybe_unused amd_pmc_resume(struct device *dev)
|
||||||
amd_pmc_send_cmd(pdev, 0, NULL, SMU_MSG_LOG_DUMP_DATA, 0);
|
amd_pmc_send_cmd(pdev, 0, NULL, SMU_MSG_LOG_DUMP_DATA, 0);
|
||||||
|
|
||||||
/* Dump the IdleMask to see the blockers */
|
/* Dump the IdleMask to see the blockers */
|
||||||
amd_pmc_idlemask_read(pdev, dev, NULL);
|
amd_pmc_idlemask_read(pdev, pdev->dev, NULL);
|
||||||
|
|
||||||
/* Write data incremented by 1 to distinguish in stb_read */
|
/* Write data incremented by 1 to distinguish in stb_read */
|
||||||
if (enable_stb)
|
if (enable_stb)
|
||||||
|
@ -711,13 +709,11 @@ static int __maybe_unused amd_pmc_resume(struct device *dev)
|
||||||
|
|
||||||
/* Notify on failed entry */
|
/* Notify on failed entry */
|
||||||
amd_pmc_validate_deepest(pdev);
|
amd_pmc_validate_deepest(pdev);
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct dev_pm_ops amd_pmc_pm_ops = {
|
static struct acpi_s2idle_dev_ops amd_pmc_s2idle_dev_ops = {
|
||||||
.suspend_noirq = amd_pmc_suspend,
|
.prepare = amd_pmc_s2idle_prepare,
|
||||||
.resume_noirq = amd_pmc_resume,
|
.restore = amd_pmc_s2idle_restore,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct pci_device_id pmc_pci_ids[] = {
|
static const struct pci_device_id pmc_pci_ids[] = {
|
||||||
|
@ -884,6 +880,10 @@ static int amd_pmc_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
amd_pmc_get_smu_version(dev);
|
amd_pmc_get_smu_version(dev);
|
||||||
platform_set_drvdata(pdev, dev);
|
platform_set_drvdata(pdev, dev);
|
||||||
|
err = acpi_register_lps0_dev(&amd_pmc_s2idle_dev_ops);
|
||||||
|
if (err)
|
||||||
|
dev_warn(dev->dev, "failed to register LPS0 sleep handler, expect increased power consumption\n");
|
||||||
|
|
||||||
amd_pmc_dbgfs_register(dev);
|
amd_pmc_dbgfs_register(dev);
|
||||||
cpu_latency_qos_add_request(&dev->amd_pmc_pm_qos_req, PM_QOS_DEFAULT_VALUE);
|
cpu_latency_qos_add_request(&dev->amd_pmc_pm_qos_req, PM_QOS_DEFAULT_VALUE);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -897,6 +897,7 @@ static int amd_pmc_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct amd_pmc_dev *dev = platform_get_drvdata(pdev);
|
struct amd_pmc_dev *dev = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
|
acpi_unregister_lps0_dev(&amd_pmc_s2idle_dev_ops);
|
||||||
amd_pmc_dbgfs_unregister(dev);
|
amd_pmc_dbgfs_unregister(dev);
|
||||||
pci_dev_put(dev->rdev);
|
pci_dev_put(dev->rdev);
|
||||||
mutex_destroy(&dev->lock);
|
mutex_destroy(&dev->lock);
|
||||||
|
@ -917,7 +918,6 @@ static struct platform_driver amd_pmc_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "amd_pmc",
|
.name = "amd_pmc",
|
||||||
.acpi_match_table = amd_pmc_acpi_ids,
|
.acpi_match_table = amd_pmc_acpi_ids,
|
||||||
.pm = &amd_pmc_pm_ops,
|
|
||||||
},
|
},
|
||||||
.probe = amd_pmc_probe,
|
.probe = amd_pmc_probe,
|
||||||
.remove = amd_pmc_remove,
|
.remove = amd_pmc_remove,
|
||||||
|
|
Loading…
Add table
Reference in a new issue