aboutsummarylogtreecommitdiffstats
path: root/9001-v5.14.1-s0ix-patch-2021-09-03.patch
diff options
context:
space:
mode:
Diffstat (limited to '9001-v5.14.1-s0ix-patch-2021-09-03.patch')
-rw-r--r--9001-v5.14.1-s0ix-patch-2021-09-03.patch766
1 files changed, 766 insertions, 0 deletions
diff --git a/9001-v5.14.1-s0ix-patch-2021-09-03.patch b/9001-v5.14.1-s0ix-patch-2021-09-03.patch
new file mode 100644
index 000000000000..21d22c496a3a
--- /dev/null
+++ b/9001-v5.14.1-s0ix-patch-2021-09-03.patch
@@ -0,0 +1,766 @@
+From 20d622ad8d682cdfa8d2db3aac2e2940fb6b7f37 Mon Sep 17 00:00:00 2001
+From: Scott B <arglebargle@arglebargle.dev>
+Date: Fri, 3 Sep 2021 06:18:48 -0700
+Subject: [PATCH] v5.14.1 s0ix patch 2021-09-03
+
+Squashed commit of the following:
+
+commit 59a128d473a903fc256ca20b05a83aedae570fef
+Author: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
+Date: Tue Aug 31 17:36:12 2021 +0530
+
+ pinctrl: amd: Add irq field data
+
+ pinctrl_amd use gpiochip_get_data() to get their local state containers
+ back from the gpiochip passed as amd_gpio chip data.
+
+ Hence added irq field data to get directly using amd_gpio chip data.
+
+ Signed-off-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
+
+commit d48c21c63803949bb4655e93b0fb064d56db5682
+Author: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
+Date: Tue Aug 31 17:36:13 2021 +0530
+
+ pinctrl: amd: Handle wake-up interrupt
+
+ Enable/disable power management wakeup mode, which is disabled by
+ default. enable_irq_wake enables wakes the system from sleep.
+
+ Hence added enable/disable irq_wake to handle wake-up interrupt.
+
+ Signed-off-by: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
+
+commit 2219e4d484f61a7234a1744fe7f44255850264fb
+Author: Mario Limonciello <mario.limonciello@amd.com>
+Date: Tue Aug 31 11:36:19 2021 -0500
+
+ ACPI: PM: s2idle: Run both AMD and Microsoft methods if both are supported
+
+ It was reported that on "HP ENVY x360" that power LED does not come back
+ on, certain keys like brightness controls do not work, and the fan never
+ spins up, even under load.
+
+ In analysis of the SSDT it's clear that the Microsoft UUID doesn't provide
+ functional support, but rather the AMD UUID should be supporting this
+ system.
+
+ Because this is a gap in the expected logic, confirmation with internal
+ team is that AMD uPEP *does* run even when Microsoft UUID present, but
+ most OEM systems have adopted value of "0x3" for supported functions and
+ hence nothing runs.
+
+ Henceforth add support for running both Microsoft and AMD methods. This
+ approach will also allow the same logic on Intel systems if desired at a
+ future time as well by pulling the evaluation of
+ `lps0_dsm_func_mask_microsoft` out of the if block for
+ `acpi_s2idle_vendor_amd`.
+
+ BugLink: https://gitlab.freedesktop.org/drm/amd/-/issues/1691
+ Reported-by: Maxwell Beck <max@ryt.one>
+ Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
+
+commit 290e605b95a082a6cef455fcb89e263271db9ee5
+Author: Scott B <28817345+foundObjects@users.noreply.github.com>
+Date: Wed Jul 21 18:10:28 2021 -0700
+
+ amd-pmc smu register dump for diagnostics
+
+ patch this per Mario's request:
+ https://gitlab.freedesktop.org/drm/amd/-/issues/1629#note_1000332
+
+commit 69a3e85d633dbdac57017feb9a059b97c8937034
+Author: Scott B <28817345+foundObjects@users.noreply.github.com>
+Date: Tue Jul 20 23:33:01 2021 -0700
+
+ drm/amd/pm: Add information about SMU12 firmware version
+
+ hacky manual import of: https://lists.freedesktop.org/archives/amd-gfx/2021-July/066835.html
+
+ This information is useful for root causing issues with S0ix.
+
+ Signed-off-by: Mario Limonciello <mario.limonciello at amd.com>
+
+commit 24c0c263a463b39c74216a640873fd2060d82156
+Author: Scott B <28817345+foundObjects@users.noreply.github.com>
+Date: Tue Jul 20 23:31:31 2021 -0700
+
+ drm/amd/pm: Add information about SMU11 firmware version
+
+ hacky manual import of: https://lists.freedesktop.org/archives/amd-gfx/2021-July/066834.html
+
+ This information is useful for root causing issues with S0ix.
+
+ Signed-off-by: Mario Limonciello <mario.limonciello at amd.com>
+
+commit 1406ea8541b9148c692abd0b97de373df3db413f
+Author: Guchun Chen <guchun.chen@amd.com>
+Date: Thu Jul 22 17:20:21 2021 +0800
+
+ drm/amdgpu: fix build error
+
+ drivers/gpu/drm/amd/amdgpu/../pm/swsmu/smu_cmn.c: In function 'smu_cmn_send_msg_without_waiting':
+ drivers/gpu/drm/amd/amdgpu/../pm/swsmu/smu_cmn.c:259:15: error: 'struct amdgpu_device' has no member named 'in_pci_err_recovery'
+ if (smu->adev->in_pci_err_recovery)
+ ^~
+ CC [M] drivers/staging/rtl8192u/ieee80211/ieee80211_tx.o
+ scripts/Makefile.build:272: recipe for target 'drivers/gpu/drm/amd/amdgpu/../pm/swsmu/smu_cmn.o' failed
+ make[7]: *** [drivers/gpu/drm/amd/amdgpu/../pm/swsmu/smu_cmn.o] Error 1
+ scripts/Makefile.build:515: recipe for target 'drivers/gpu/drm/amd/amdgpu' failed
+ make[6]: *** [drivers/gpu/drm/amd/amdgpu] Error 2
+ make[6]: *** Waiting for unfinished jobs....
+
+ Fixes: e070ba49f3a7 drm/amd/pm: Fix a bug communicating with the SMU (v5)
+ Signed-off-by: Guchun Chen <guchun.chen@amd.com>
+ Reviewed-by: Luben Tuikov <luben.tuikov@amd.com>
+
+commit ec7f3b175ad85caf3289506ae95b27ddb106416e
+Author: Luben Tuikov <luben.tuikov@amd.com>
+Date: Fri Jul 9 23:33:11 2021 -0400
+
+ drm/amd/pm: Fix a bug communicating with the SMU (v5)
+
+ This fixes a bug which if we probe a non-existing
+ I2C device, and the SMU returns 0xFF, from then on
+ we can never communicate with the SMU, because the
+ code before this patch reads and interprets 0xFF
+ as a terminal error, and thus we never write 0
+ into register 90 to clear the status (and
+ subsequently send a new command to the SMU.)
+
+ It is not an error that the SMU returns status
+ 0xFF. This means that the SMU executed the last
+ command successfully (execution status), but the
+ command result is an error of some sort (execution
+ result), depending on what the command was.
+
+ When doing a status check of the SMU, before we
+ send a new command, the only status which
+ precludes us from sending a new command is 0--the
+ SMU hasn't finished executing a previous command,
+ and 0xFC--the SMU is busy.
+
+ This bug was seen as the following line in the
+ kernel log,
+
+ amdgpu: Msg issuing pre-check failed(0xff) and SMU may be not in the right state!
+
+ when subsequent SMU commands, not necessarily
+ related to I2C, were sent to the SMU.
+
+ This patch fixes this bug.
+
+ v2: Add a comment to the description of
+ __smu_cmn_poll_stat() to explain why we're NOT
+ defining the SMU FW return codes as macros, but
+ are instead hard-coding them. Such a change, can
+ be followed up by a subsequent patch.
+
+ v3: The changes are,
+ a) Add comments to break labels in
+ __smu_cmn_reg2errno().
+
+ b) When an unknown/unspecified/undefined result is
+ returned back from the SMU, map that to
+ -EREMOTEIO, to distinguish failure at the SMU
+ FW.
+
+ c) Add kernel-doc to
+ smu_cmn_send_msg_without_waiting(),
+ smu_cmn_wait_for_response(),
+ smu_cmn_send_smc_msg_with_param().
+
+ d) In smu_cmn_send_smc_msg_with_param(), since we
+ wait for completion of the command, if the
+ result of the completion is
+ undefined/unknown/unspecified, we print that to
+ the kernel log.
+
+ v4: a) Add macros as requested, though redundant, to
+ be removed when SMU consolidates for all
+ ASICs--see comment in code.
+ b) Get out if the SMU code is unknown.
+
+ v5: Rename the macro names.
+
+ Cc: Alex Deucher <Alexander.Deucher@amd.com>
+ Cc: Evan Quan <evan.quan@amd.com>
+ Cc: Lijo Lazar <Lijo.Lazar@amd.com>
+ Fixes: fcb1fe9c9e0031 ("drm/amd/powerplay: pre-check the SMU state before issuing message")
+ Signed-off-by: Luben Tuikov <luben.tuikov@amd.com>
+ Reviewed-by: Alex Deucher <Alexander.Deucher@amd.com>
+---
+ drivers/acpi/x86/s2idle.c | 67 ++--
+ .../gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c | 3 +
+ .../gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c | 3 +
+ drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c | 290 +++++++++++++++---
+ drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h | 3 +-
+ drivers/pinctrl/pinctrl-amd.c | 19 +-
+ drivers/pinctrl/pinctrl-amd.h | 1 +
+ drivers/platform/x86/amd-pmc.c | 1 +
+ 8 files changed, 306 insertions(+), 81 deletions(-)
+
+diff --git a/drivers/acpi/x86/s2idle.c b/drivers/acpi/x86/s2idle.c
+index 3a308461246a..7d1976e5dd8b 100644
+--- a/drivers/acpi/x86/s2idle.c
++++ b/drivers/acpi/x86/s2idle.c
+@@ -449,25 +449,30 @@ int acpi_s2idle_prepare_late(void)
+ if (pm_debug_messages_on)
+ lpi_check_constraints();
+
+- if (lps0_dsm_func_mask_microsoft > 0) {
++ /* screen off */
++ if (lps0_dsm_func_mask > 0)
++ acpi_sleep_run_lps0_dsm(acpi_s2idle_vendor_amd() ?
++ ACPI_LPS0_SCREEN_OFF_AMD :
++ ACPI_LPS0_SCREEN_OFF,
++ lps0_dsm_func_mask, lps0_dsm_guid);
++
++ if (lps0_dsm_func_mask_microsoft > 0)
+ acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_OFF,
+ lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
++
++ /* lps0 entry */
++ if (lps0_dsm_func_mask > 0)
++ acpi_sleep_run_lps0_dsm(acpi_s2idle_vendor_amd() ?
++ ACPI_LPS0_ENTRY_AMD :
++ ACPI_LPS0_ENTRY,
++ lps0_dsm_func_mask, lps0_dsm_guid);
++ if (lps0_dsm_func_mask_microsoft > 0) {
++ acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY,
++ lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
++ /* modern standby entry */
+ acpi_sleep_run_lps0_dsm(ACPI_LPS0_MS_ENTRY,
+ lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
+- acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY,
+- lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
+- } else if (acpi_s2idle_vendor_amd()) {
+- acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_OFF_AMD,
+- lps0_dsm_func_mask, lps0_dsm_guid);
+- acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY_AMD,
+- lps0_dsm_func_mask, lps0_dsm_guid);
+- } else {
+- acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_OFF,
+- lps0_dsm_func_mask, lps0_dsm_guid);
+- acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY,
+- lps0_dsm_func_mask, lps0_dsm_guid);
+ }
+-
+ return 0;
+ }
+
+@@ -476,24 +481,30 @@ void acpi_s2idle_restore_early(void)
+ if (!lps0_device_handle || sleep_no_lps0)
+ return;
+
+- if (lps0_dsm_func_mask_microsoft > 0) {
+- acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT,
+- lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
++ /* mdoern standby exit */
++ if (lps0_dsm_func_mask_microsoft > 0)
+ acpi_sleep_run_lps0_dsm(ACPI_LPS0_MS_EXIT,
+ lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
++
++ /* lps0 exit */
++ if (lps0_dsm_func_mask > 0)
++ acpi_sleep_run_lps0_dsm(acpi_s2idle_vendor_amd() ?
++ ACPI_LPS0_EXIT_AMD :
++ ACPI_LPS0_EXIT,
++ lps0_dsm_func_mask, lps0_dsm_guid);
++ if (lps0_dsm_func_mask_microsoft > 0)
++ acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT,
++ lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
++
++ /* screen on */
++ if (lps0_dsm_func_mask_microsoft > 0)
+ acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_ON,
+ lps0_dsm_func_mask_microsoft, lps0_dsm_guid_microsoft);
+- } else if (acpi_s2idle_vendor_amd()) {
+- acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT_AMD,
+- lps0_dsm_func_mask, lps0_dsm_guid);
+- acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_ON_AMD,
+- lps0_dsm_func_mask, lps0_dsm_guid);
+- } else {
+- acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT,
+- lps0_dsm_func_mask, lps0_dsm_guid);
+- acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_ON,
+- lps0_dsm_func_mask, lps0_dsm_guid);
+- }
++ if (lps0_dsm_func_mask > 0)
++ acpi_sleep_run_lps0_dsm(acpi_s2idle_vendor_amd() ?
++ ACPI_LPS0_SCREEN_ON_AMD :
++ ACPI_LPS0_SCREEN_ON,
++ lps0_dsm_func_mask, lps0_dsm_guid);
+ }
+
+ static const struct platform_s2idle_ops acpi_s2idle_ops_lps0 = {
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
+index 0a5d46ac9ccd..626d7c2bdf66 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c
+@@ -272,6 +272,9 @@ int smu_v11_0_check_fw_version(struct smu_context *smu)
+ break;
+ }
+
++ dev_info(smu->adev->dev, "smu fw reported version = 0x%08x (%d.%d.%d)\n",
++ smu_version, smu_major, smu_minor, smu_debug);
++
+ /*
+ * 1. if_version mismatch is not critical as our fw is designed
+ * to be backward compatible.
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c b/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c
+index d60b8c5e8715..00ebc381a605 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c
+@@ -88,6 +88,9 @@ int smu_v12_0_check_fw_version(struct smu_context *smu)
+ if (smu->is_apu)
+ adev->pm.fw_version = smu_version;
+
++ dev_info(smu->adev->dev, "smu fw reported version = 0x%08x (%d.%d.%d)\n",
++ smu_version, smu_major, smu_minor, smu_debug);
++
+ /*
+ * 1. if_version mismatch is not critical as our fw is designed
+ * to be backward compatible.
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
+index e802f9a95f08..a0e2111eb783 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.c
+@@ -55,7 +55,7 @@
+
+ #undef __SMU_DUMMY_MAP
+ #define __SMU_DUMMY_MAP(type) #type
+-static const char* __smu_message_names[] = {
++static const char * const __smu_message_names[] = {
+ SMU_MESSAGE_TYPES
+ };
+
+@@ -76,55 +76,258 @@ static void smu_cmn_read_arg(struct smu_context *smu,
+ *arg = RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_82);
+ }
+
+-int smu_cmn_wait_for_response(struct smu_context *smu)
++/* Redefine the SMU error codes here.
++ *
++ * Note that these definitions are redundant and should be removed
++ * when the SMU has exported a unified header file containing these
++ * macros, which header file we can just include and use the SMU's
++ * macros. At the moment, these error codes are defined by the SMU
++ * per-ASIC unfortunately, yet we're a one driver for all ASICs.
++ */
++#define SMU_RESP_NONE 0
++#define SMU_RESP_OK 1
++#define SMU_RESP_CMD_FAIL 0xFF
++#define SMU_RESP_CMD_UNKNOWN 0xFE
++#define SMU_RESP_CMD_BAD_PREREQ 0xFD
++#define SMU_RESP_BUSY_OTHER 0xFC
++#define SMU_RESP_DEBUG_END 0xFB
++
++/**
++ * __smu_cmn_poll_stat -- poll for a status from the SMU
++ * smu: a pointer to SMU context
++ *
++ * Returns the status of the SMU, which could be,
++ * 0, the SMU is busy with your previous command;
++ * 1, execution status: success, execution result: success;
++ * 0xFF, execution status: success, execution result: failure;
++ * 0xFE, unknown command;
++ * 0xFD, valid command, but bad (command) prerequisites;
++ * 0xFC, the command was rejected as the SMU is busy;
++ * 0xFB, "SMC_Result_DebugDataDumpEnd".
++ *
++ * The values here are not defined by macros, because I'd rather we
++ * include a single header file which defines them, which is
++ * maintained by the SMU FW team, so that we're impervious to firmware
++ * changes. At the moment those values are defined in various header
++ * files, one for each ASIC, yet here we're a single ASIC-agnostic
++ * interface. Such a change can be followed-up by a subsequent patch.
++ */
++static u32 __smu_cmn_poll_stat(struct smu_context *smu)
+ {
+ struct amdgpu_device *adev = smu->adev;
+- uint32_t cur_value, i, timeout = adev->usec_timeout * 20;
++ int timeout = adev->usec_timeout * 20;
++ u32 reg;
+
+- for (i = 0; i < timeout; i++) {
+- cur_value = RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90);
+- if ((cur_value & MP1_C2PMSG_90__CONTENT_MASK) != 0)
+- return cur_value;
++ for ( ; timeout > 0; timeout--) {
++ reg = RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90);
++ if ((reg & MP1_C2PMSG_90__CONTENT_MASK) != 0)
++ break;
+
+ udelay(1);
+ }
+
+- /* timeout means wrong logic */
+- if (i == timeout)
+- return -ETIME;
+-
+- return RREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90);
++ return reg;
+ }
+
+-int smu_cmn_send_msg_without_waiting(struct smu_context *smu,
+- uint16_t msg, uint32_t param)
++static void __smu_cmn_reg_print_error(struct smu_context *smu,
++ u32 reg_c2pmsg_90,
++ int msg_index,
++ u32 param,
++ enum smu_message_type msg)
+ {
+ struct amdgpu_device *adev = smu->adev;
+- int ret;
++ const char *message = smu_get_message_name(smu, msg);
+
+- ret = smu_cmn_wait_for_response(smu);
+- if (ret != 0x1) {
+- dev_err(adev->dev, "Msg issuing pre-check failed(0x%x) and "
+- "SMU may be not in the right state!\n", ret);
+- if (ret != -ETIME)
+- ret = -EIO;
+- return ret;
++ switch (reg_c2pmsg_90) {
++ case SMU_RESP_NONE:
++ dev_err_ratelimited(adev->dev,
++ "SMU: I'm not done with your previous command!");
++ break;
++ case SMU_RESP_OK:
++ /* The SMU executed the command. It completed with a
++ * successful result.
++ */
++ break;
++ case SMU_RESP_CMD_FAIL:
++ /* The SMU executed the command. It completed with an
++ * unsuccessful result.
++ */
++ break;
++ case SMU_RESP_CMD_UNKNOWN:
++ dev_err_ratelimited(adev->dev,
++ "SMU: unknown command: index:%d param:0x%08X message:%s",
++ msg_index, param, message);
++ break;
++ case SMU_RESP_CMD_BAD_PREREQ:
++ dev_err_ratelimited(adev->dev,
++ "SMU: valid command, bad prerequisites: index:%d param:0x%08X message:%s",
++ msg_index, param, message);
++ break;
++ case SMU_RESP_BUSY_OTHER:
++ dev_err_ratelimited(adev->dev,
++ "SMU: I'm very busy for your command: index:%d param:0x%08X message:%s",
++ msg_index, param, message);
++ break;
++ case SMU_RESP_DEBUG_END:
++ dev_err_ratelimited(adev->dev,
++ "SMU: I'm debugging!");
++ break;
++ default:
++ dev_err_ratelimited(adev->dev,
++ "SMU: response:0x%08X for index:%d param:0x%08X message:%s?",
++ reg_c2pmsg_90, msg_index, param, message);
++ break;
+ }
++}
++
++static int __smu_cmn_reg2errno(struct smu_context *smu, u32 reg_c2pmsg_90)
++{
++ int res;
++
++ switch (reg_c2pmsg_90) {
++ case SMU_RESP_NONE:
++ /* The SMU is busy--still executing your command.
++ */
++ res = -ETIME;
++ break;
++ case SMU_RESP_OK:
++ res = 0;
++ break;
++ case SMU_RESP_CMD_FAIL:
++ /* Command completed successfully, but the command
++ * status was failure.
++ */
++ res = -EIO;
++ break;
++ case SMU_RESP_CMD_UNKNOWN:
++ /* Unknown command--ignored by the SMU.
++ */
++ res = -EOPNOTSUPP;
++ break;
++ case SMU_RESP_CMD_BAD_PREREQ:
++ /* Valid command--bad prerequisites.
++ */
++ res = -EINVAL;
++ break;
++ case SMU_RESP_BUSY_OTHER:
++ /* The SMU is busy with other commands. The client
++ * should retry in 10 us.
++ */
++ res = -EBUSY;
++ break;
++ default:
++ /* Unknown or debug response from the SMU.
++ */
++ res = -EREMOTEIO;
++ break;
++ }
++
++ return res;
++}
++
++static void __smu_cmn_send_msg(struct smu_context *smu,
++ u16 msg,
++ u32 param)
++{
++ struct amdgpu_device *adev = smu->adev;
+
+ WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_90, 0);
+ WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_82, param);
+ WREG32_SOC15(MP1, 0, mmMP1_SMN_C2PMSG_66, msg);
+-
+- return 0;
+ }
+
++/**
++ * smu_cmn_send_msg_without_waiting -- send the message; don't wait for status
++ * @smu: pointer to an SMU context
++ * @msg_index: message index
++ * @param: message parameter to send to the SMU
++ *
++ * Send a message to the SMU with the parameter passed. Do not wait
++ * for status/result of the message, thus the "without_waiting".
++ *
++ * Return 0 on success, -errno on error if we weren't able to _send_
++ * the message for some reason. See __smu_cmn_reg2errno() for details
++ * of the -errno.
++ */
++int smu_cmn_send_msg_without_waiting(struct smu_context *smu,
++ uint16_t msg_index,
++ uint32_t param)
++{
++ u32 reg;
++ int res;
++
++ if (smu->adev->no_hw_access)
++ return 0;
++
++ mutex_lock(&smu->message_lock);
++ reg = __smu_cmn_poll_stat(smu);
++ res = __smu_cmn_reg2errno(smu, reg);
++ if (reg == SMU_RESP_NONE ||
++ reg == SMU_RESP_BUSY_OTHER ||
++ res == -EREMOTEIO)
++ goto Out;
++ __smu_cmn_send_msg(smu, msg_index, param);
++ res = 0;
++Out:
++ mutex_unlock(&smu->message_lock);
++ return res;
++}
++
++/**
++ * smu_cmn_wait_for_response -- wait for response from the SMU
++ * @smu: pointer to an SMU context
++ *
++ * Wait for status from the SMU.
++ *
++ * Return 0 on success, -errno on error, indicating the execution
++ * status and result of the message being waited for. See
++ * __smu_cmn_reg2errno() for details of the -errno.
++ */
++int smu_cmn_wait_for_response(struct smu_context *smu)
++{
++ u32 reg;
++
++ reg = __smu_cmn_poll_stat(smu);
++ return __smu_cmn_reg2errno(smu, reg);
++}
++
++/**
++ * smu_cmn_send_smc_msg_with_param -- send a message with parameter
++ * @smu: pointer to an SMU context
++ * @msg: message to send
++ * @param: parameter to send to the SMU
++ * @read_arg: pointer to u32 to return a value from the SMU back
++ * to the caller
++ *
++ * Send the message @msg with parameter @param to the SMU, wait for
++ * completion of the command, and return back a value from the SMU in
++ * @read_arg pointer.
++ *
++ * Return 0 on success, -errno on error, if we weren't able to send
++ * the message or if the message completed with some kind of
++ * error. See __smu_cmn_reg2errno() for details of the -errno.
++ *
++ * If we weren't able to send the message to the SMU, we also print
++ * the error to the standard log.
++ *
++ * Command completion status is printed only if the -errno is
++ * -EREMOTEIO, indicating that the SMU returned back an
++ * undefined/unknown/unspecified result. All other cases are
++ * well-defined, not printed, but instead given back to the client to
++ * decide what further to do.
++ *
++ * The return value, @read_arg is read back regardless, to give back
++ * more information to the client, which on error would most likely be
++ * @param, but we can't assume that. This also eliminates more
++ * conditionals.
++ */
+ int smu_cmn_send_smc_msg_with_param(struct smu_context *smu,
+ enum smu_message_type msg,
+ uint32_t param,
+ uint32_t *read_arg)
+ {
+- struct amdgpu_device *adev = smu->adev;
+- int ret = 0, index = 0;
++ int res, index;
++ u32 reg;
+
+ if (smu->adev->no_hw_access)
+ return 0;
+@@ -136,31 +339,24 @@ int smu_cmn_send_smc_msg_with_param(struct smu_context *smu,
+ return index == -EACCES ? 0 : index;
+
+ mutex_lock(&smu->message_lock);
+- ret = smu_cmn_send_msg_without_waiting(smu, (uint16_t)index, param);
+- if (ret)
+- goto out;
+-
+- ret = smu_cmn_wait_for_response(smu);
+- if (ret != 0x1) {
+- if (ret == -ETIME) {
+- dev_err(adev->dev, "message: %15s (%d) \tparam: 0x%08x is timeout (no response)\n",
+- smu_get_message_name(smu, msg), index, param);
+- } else {
+- dev_err(adev->dev, "failed send message: %15s (%d) \tparam: 0x%08x response %#x\n",
+- smu_get_message_name(smu, msg), index, param,
+- ret);
+- ret = -EIO;
+- }
+- goto out;
++ reg = __smu_cmn_poll_stat(smu);
++ res = __smu_cmn_reg2errno(smu, reg);
++ if (reg == SMU_RESP_NONE ||
++ reg == SMU_RESP_BUSY_OTHER ||
++ res == -EREMOTEIO) {
++ __smu_cmn_reg_print_error(smu, reg, index, param, msg);
++ goto Out;
+ }
+-
++ __smu_cmn_send_msg(smu, (uint16_t) index, param);
++ reg = __smu_cmn_poll_stat(smu);
++ res = __smu_cmn_reg2errno(smu, reg);
++ if (res == -EREMOTEIO)
++ __smu_cmn_reg_print_error(smu, reg, index, param, msg);
+ if (read_arg)
+ smu_cmn_read_arg(smu, read_arg);
+-
+- ret = 0; /* 0 as driver return value */
+-out:
++Out:
+ mutex_unlock(&smu->message_lock);
+- return ret;
++ return res;
+ }
+
+ int smu_cmn_send_smc_msg(struct smu_context *smu,
+diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h
+index 9add5f16ff56..16993daa2ae0 100644
+--- a/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h
++++ b/drivers/gpu/drm/amd/pm/swsmu/smu_cmn.h
+@@ -27,7 +27,8 @@
+
+ #if defined(SWSMU_CODE_LAYER_L2) || defined(SWSMU_CODE_LAYER_L3) || defined(SWSMU_CODE_LAYER_L4)
+ int smu_cmn_send_msg_without_waiting(struct smu_context *smu,
+- uint16_t msg, uint32_t param);
++ uint16_t msg_index,
++ uint32_t param);
+ int smu_cmn_send_smc_msg_with_param(struct smu_context *smu,
+ enum smu_message_type msg,
+ uint32_t param,
+diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c
+index 5b764740b829..d19974aceb2e 100644
+--- a/drivers/pinctrl/pinctrl-amd.c
++++ b/drivers/pinctrl/pinctrl-amd.c
+@@ -445,6 +445,7 @@ static int amd_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
+ struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
+ struct amd_gpio *gpio_dev = gpiochip_get_data(gc);
+ u32 wake_mask = BIT(WAKE_CNTRL_OFF_S0I3) | BIT(WAKE_CNTRL_OFF_S3);
++ int err;
+
+ raw_spin_lock_irqsave(&gpio_dev->lock, flags);
+ pin_reg = readl(gpio_dev->base + (d->hwirq)*4);
+@@ -457,6 +458,15 @@ static int amd_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
+ writel(pin_reg, gpio_dev->base + (d->hwirq)*4);
+ raw_spin_unlock_irqrestore(&gpio_dev->lock, flags);
+
++ if (on)
++ err = enable_irq_wake(gpio_dev->irq);
++ else
++ err = disable_irq_wake(gpio_dev->irq);
++
++ if (err)
++ dev_err(&gpio_dev->pdev->dev, "failed to %s wake-up interrupt\n",
++ on ? "enable" : "disable");
++
+ return 0;
+ }
+
+@@ -904,7 +914,6 @@ static struct pinctrl_desc amd_pinctrl_desc = {
+ static int amd_gpio_probe(struct platform_device *pdev)
+ {
+ int ret = 0;
+- int irq_base;
+ struct resource *res;
+ struct amd_gpio *gpio_dev;
+ struct gpio_irq_chip *girq;
+@@ -927,9 +936,9 @@ static int amd_gpio_probe(struct platform_device *pdev)
+ if (!gpio_dev->base)
+ return -ENOMEM;
+
+- irq_base = platform_get_irq(pdev, 0);
+- if (irq_base < 0)
+- return irq_base;
++ gpio_dev->irq = platform_get_irq(pdev, 0);
++ if (gpio_dev->irq < 0)
++ return gpio_dev->irq;
+
+ #ifdef CONFIG_PM_SLEEP
+ gpio_dev->saved_regs = devm_kcalloc(&pdev->dev, amd_pinctrl_desc.npins,
+@@ -989,7 +998,7 @@ static int amd_gpio_probe(struct platform_device *pdev)
+ goto out2;
+ }
+
+- ret = devm_request_irq(&pdev->dev, irq_base, amd_gpio_irq_handler,
++ ret = devm_request_irq(&pdev->dev, gpio_dev->irq, amd_gpio_irq_handler,
+ IRQF_SHARED, KBUILD_MODNAME, gpio_dev);
+ if (ret)
+ goto out2;
+diff --git a/drivers/pinctrl/pinctrl-amd.h b/drivers/pinctrl/pinctrl-amd.h
+index 95e763424042..1d4317073654 100644
+--- a/drivers/pinctrl/pinctrl-amd.h
++++ b/drivers/pinctrl/pinctrl-amd.h
+@@ -98,6 +98,7 @@ struct amd_gpio {
+ struct resource *res;
+ struct platform_device *pdev;
+ u32 *saved_regs;
++ int irq;
+ };
+
+ /* KERNCZ configuration*/
+diff --git a/drivers/platform/x86/amd-pmc.c b/drivers/platform/x86/amd-pmc.c
+index 3481479a2942..52a88c9bc0ab 100644
+--- a/drivers/platform/x86/amd-pmc.c
++++ b/drivers/platform/x86/amd-pmc.c
+@@ -270,6 +270,7 @@ static int amd_pmc_send_cmd(struct amd_pmc_dev *dev, bool set, u32 *data, u8 msg
+ u32 val;
+
+ mutex_lock(&dev->lock);
++ amd_pmc_dump_registers(dev);
+ /* Wait until we get a valid response */
+ rc = readx_poll_timeout(ioread32, dev->regbase + AMD_PMC_REGISTER_RESPONSE,
+ val, val != 0, PMC_MSG_DELAY_MIN_US,
+--
+2.33.0
+