]> git.baikalelectronics.ru Git - kernel.git/commitdiff
ASoC: rockchip: i2s: Fix regmap_ops hang
authorSugar Zhang <sugar.zhang@rock-chips.com>
Thu, 26 Aug 2021 04:01:50 +0000 (12:01 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 22 Sep 2021 10:26:35 +0000 (12:26 +0200)
[ Upstream commit 53ca9b9777b95cdd689181d7c547e38dc79adad0 ]

API 'set_fmt' maybe called when PD is off, in the situation,
any register access will hang the system. so, enable PD
before r/w register.

Signed-off-by: Sugar Zhang <sugar.zhang@rock-chips.com>
Link: https://lore.kernel.org/r/1629950520-14190-4-git-send-email-sugar.zhang@rock-chips.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
sound/soc/rockchip/rockchip_i2s.c

index 61c984f10d8e61199b7c02e287532039c6f3d9ed..f48b146cd96a1d9cbe34e41d3a9d900e731d83b1 100644 (file)
@@ -186,7 +186,9 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
 {
        struct rk_i2s_dev *i2s = to_info(cpu_dai);
        unsigned int mask = 0, val = 0;
+       int ret = 0;
 
+       pm_runtime_get_sync(cpu_dai->dev);
        mask = I2S_CKR_MSS_MASK;
        switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
        case SND_SOC_DAIFMT_CBS_CFS:
@@ -199,7 +201,8 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
                i2s->is_master_mode = false;
                break;
        default:
-               return -EINVAL;
+               ret = -EINVAL;
+               goto err_pm_put;
        }
 
        regmap_update_bits(i2s->regmap, I2S_CKR, mask, val);
@@ -213,7 +216,8 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
                val = I2S_CKR_CKP_POS;
                break;
        default:
-               return -EINVAL;
+               ret = -EINVAL;
+               goto err_pm_put;
        }
 
        regmap_update_bits(i2s->regmap, I2S_CKR, mask, val);
@@ -236,7 +240,8 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
                val = I2S_TXCR_TFS_PCM | I2S_TXCR_PBM_MODE(1);
                break;
        default:
-               return -EINVAL;
+               ret = -EINVAL;
+               goto err_pm_put;
        }
 
        regmap_update_bits(i2s->regmap, I2S_TXCR, mask, val);
@@ -259,12 +264,16 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
                val = I2S_RXCR_TFS_PCM | I2S_RXCR_PBM_MODE(1);
                break;
        default:
-               return -EINVAL;
+               ret = -EINVAL;
+               goto err_pm_put;
        }
 
        regmap_update_bits(i2s->regmap, I2S_RXCR, mask, val);
 
-       return 0;
+err_pm_put:
+       pm_runtime_put(cpu_dai->dev);
+
+       return ret;
 }
 
 static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream,