ASoC: SOF: add mutex to protect the dsp_power_state access
authorKeyon Jie <yang.jie@linux.intel.com>
Tue, 5 Jan 2021 15:56:40 +0000 (17:56 +0200)
committerMark Brown <broonie@kernel.org>
Tue, 12 Jan 2021 16:40:23 +0000 (16:40 +0000)
There could be more than one thread read/write the dsp_power_state
simultaneously (e.g. hda_dsp_d0i3_work and sof_ipc_tx_message), add a
mutex power_state_access to make sure the access to it is mutually
exclusive.

Signed-off-by: Keyon Jie <yang.jie@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Bard Liao <bard.liao@intel.com>
Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Link: https://lore.kernel.org/r/20210105155640.3725238-1-kai.vehmanen@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/sof/core.c
sound/soc/sof/ops.h
sound/soc/sof/sof-priv.h

index adc7c37145d6407c173c942cd58f61103f0c3bbb..2b85ef5d6092ab5082360be1fa97fe6790d2b8d6 100644 (file)
@@ -316,6 +316,7 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data)
        INIT_LIST_HEAD(&sdev->route_list);
        spin_lock_init(&sdev->ipc_lock);
        spin_lock_init(&sdev->hw_lock);
+       mutex_init(&sdev->power_state_access);
 
        if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE))
                INIT_WORK(&sdev->probe_work, sof_probe_work);
index 95e748b36903a0084e92769681d50204342449e9..4c1f9daaa6e87157b0500d4572ea13572961bdde 100644 (file)
@@ -208,11 +208,16 @@ static inline int
 snd_sof_dsp_set_power_state(struct snd_sof_dev *sdev,
                            const struct sof_dsp_power_state *target_state)
 {
+       int ret = 0;
+
+       mutex_lock(&sdev->power_state_access);
+
        if (sof_ops(sdev)->set_power_state)
-               return sof_ops(sdev)->set_power_state(sdev, target_state);
+               ret = sof_ops(sdev)->set_power_state(sdev, target_state);
 
-       /* D0 substate is not supported, do nothing here. */
-       return 0;
+       mutex_unlock(&sdev->power_state_access);
+
+       return ret;
 }
 
 /* debug */
index 68da8f797403e7624aaee7755ba67cd549839a01..28d19fa30614efdadb476932d91b03402cf35a04 100644 (file)
@@ -375,6 +375,8 @@ struct snd_sof_dev {
 
        /* current DSP power state */
        struct sof_dsp_power_state dsp_power_state;
+       /* mutex to protect the dsp_power_state access */
+       struct mutex power_state_access;
 
        /* Intended power target of system suspend */
        enum sof_system_suspend_state system_suspend_target;