summaryrefslogtreecommitdiff
path: root/drivers/platform/x86
diff options
context:
space:
mode:
authorMario Limonciello <mario.limonciello@amd.com>2022-03-10 18:09:20 +0300
committerHans de Goede <hdegoede@redhat.com>2022-03-10 20:47:55 +0300
commit854abe25ddb0d33532f15cca7eb5240b02f7db6b (patch)
tree3104483ccd9ae04dac0109dbb2ca99d24d275b35 /drivers/platform/x86
parent10b29dd7eafe1987b44866d3ee1d0d71bf622cb3 (diff)
downloadlinux-854abe25ddb0d33532f15cca7eb5240b02f7db6b.tar.xz
platform/x86: amd-pmc: Validate entry into the deepest state on resume
Currently the only way to discover if a system went into the deepest sleep state is to read from sysfs after you finished suspend. To better illustrate to users that problems have occurred, check as part of resume and display a warning. Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> Link: https://lore.kernel.org/r/20220310150920.560583-1-mario.limonciello@amd.com Reviewed-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Diffstat (limited to 'drivers/platform/x86')
-rw-r--r--drivers/platform/x86/amd-pmc.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/drivers/platform/x86/amd-pmc.c b/drivers/platform/x86/amd-pmc.c
index fc0b4d628dec..971aaabaa9c8 100644
--- a/drivers/platform/x86/amd-pmc.c
+++ b/drivers/platform/x86/amd-pmc.c
@@ -322,6 +322,28 @@ static int amd_pmc_idlemask_read(struct amd_pmc_dev *pdev, struct device *dev,
return 0;
}
+static int get_metrics_table(struct amd_pmc_dev *pdev, struct smu_metrics *table)
+{
+ if (pdev->cpu_id == AMD_CPU_ID_PCO)
+ return -ENODEV;
+ memcpy_fromio(table, pdev->smu_virt_addr, sizeof(struct smu_metrics));
+ return 0;
+}
+
+static void amd_pmc_validate_deepest(struct amd_pmc_dev *pdev)
+{
+ struct smu_metrics table;
+
+ if (get_metrics_table(pdev, &table))
+ return;
+
+ if (!table.s0i3_last_entry_status)
+ dev_warn(pdev->dev, "Last suspend didn't reach deepest state\n");
+ else
+ dev_dbg(pdev->dev, "Last suspend in deepest state for %lluus\n",
+ table.timein_s0i3_lastcapture);
+}
+
#ifdef CONFIG_DEBUG_FS
static int smu_fw_info_show(struct seq_file *s, void *unused)
{
@@ -329,11 +351,9 @@ static int smu_fw_info_show(struct seq_file *s, void *unused)
struct smu_metrics table;
int idx;
- if (dev->cpu_id == AMD_CPU_ID_PCO)
+ if (get_metrics_table(dev, &table))
return -EINVAL;
- memcpy_fromio(&table, dev->smu_virt_addr, sizeof(struct smu_metrics));
-
seq_puts(s, "\n=== SMU Statistics ===\n");
seq_printf(s, "Table Version: %d\n", table.table_version);
seq_printf(s, "Hint Count: %d\n", table.hint_count);
@@ -689,6 +709,9 @@ static int __maybe_unused amd_pmc_resume(struct device *dev)
cpu_latency_qos_update_request(&pdev->amd_pmc_pm_qos_req,
PM_QOS_DEFAULT_VALUE);
+ /* Notify on failed entry */
+ amd_pmc_validate_deepest(pdev);
+
return rc;
}