ASoC: SOF: Fix runtime pm usage counter balance after fw exception
authorPeter Ujfalusi <peter.ujfalusi@linux.intel.com>
Tue, 13 Feb 2024 11:47:29 +0000 (13:47 +0200)
committerMark Brown <broonie@kernel.org>
Tue, 13 Feb 2024 14:22:57 +0000 (14:22 +0000)
If the retain context is enabled we will unconditionally increment the
device's pm use count on each exception and when the drivers are unloaded
we do not correct this (as we don't know how many times we 'prevented
d3 entry').
Introduce a flag to make sure that we do not increment the use count more
than once and on module unload decrement the use count if needed to
balance it.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://msgid.link/r/20240213114729.7055-1-peter.ujfalusi@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/sof/core.c
sound/soc/sof/debug.c
sound/soc/sof/sof-priv.h

index 425b023b03b419957eaf01f8e15930fe6c7e0dc7..9b00ede2a486a2ff2d619ab714ed2c1665eb3463 100644 (file)
@@ -679,6 +679,16 @@ int snd_sof_device_remove(struct device *dev)
         */
        snd_sof_machine_unregister(sdev, pdata);
 
+       /*
+        * Balance the runtime pm usage count in case we are faced with an
+        * exception and we forcably prevented D3 power state to preserve
+        * context
+        */
+       if (sdev->d3_prevented) {
+               sdev->d3_prevented = false;
+               pm_runtime_put_noidle(sdev->dev);
+       }
+
        if (sdev->fw_state > SOF_FW_BOOT_NOT_STARTED) {
                sof_fw_trace_free(sdev);
                ret = snd_sof_dsp_power_down_notify(sdev);
index d547318e0d32f43feb075d18bcf4d7feba452862..7c8aafca8fdef8eb65211dcd8cbead13077a6068 100644 (file)
@@ -433,13 +433,15 @@ static void snd_sof_ipc_dump(struct snd_sof_dev *sdev)
 
 void snd_sof_handle_fw_exception(struct snd_sof_dev *sdev, const char *msg)
 {
-       if (IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_RETAIN_DSP_CONTEXT) ||
-           sof_debug_check_flag(SOF_DBG_RETAIN_CTX)) {
+       if ((IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_RETAIN_DSP_CONTEXT) ||
+           sof_debug_check_flag(SOF_DBG_RETAIN_CTX)) && !sdev->d3_prevented) {
                /* should we prevent DSP entering D3 ? */
                if (!sdev->ipc_dump_printed)
                        dev_info(sdev->dev,
                                 "Attempting to prevent DSP from entering D3 state to preserve context\n");
-               pm_runtime_get_if_in_use(sdev->dev);
+
+               if (pm_runtime_get_if_in_use(sdev->dev) == 1)
+                       sdev->d3_prevented = true;
        }
 
        /* dump vital information to the logs */
index 6d7897bf96075e05dae0f708155455bf10a38b44..5755c997a9de66e29658ca588ffd7e12ae02244a 100644 (file)
@@ -595,6 +595,7 @@ struct snd_sof_dev {
        struct list_head dfsentry_list;
        bool dbg_dump_printed;
        bool ipc_dump_printed;
+       bool d3_prevented; /* runtime pm use count incremented to prevent context lost */
 
        /* firmware loader */
        struct sof_ipc_fw_ready fw_ready;