ASoC: sti: fix possible sleep-in-atomic
authorArnaud Pouliquen <arnaud.pouliquen@st.com>
Mon, 13 Jan 2020 10:04:00 +0000 (11:04 +0100)
committerMark Brown <broonie@kernel.org>
Mon, 13 Jan 2020 15:12:26 +0000 (15:12 +0000)
Change mutex and spinlock management to avoid sleep
in atomic issue.

Signed-off-by: Arnaud Pouliquen <arnaud.pouliquen@st.com>
Link: https://lore.kernel.org/r/20200113100400.30472-1-arnaud.pouliquen@st.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/sti/uniperif_player.c

index 48ea915..2ed92c9 100644 (file)
@@ -226,7 +226,6 @@ static void uni_player_set_channel_status(struct uniperif *player,
         * sampling frequency. If no sample rate is already specified, then
         * set one.
         */
-       mutex_lock(&player->ctrl_lock);
        if (runtime) {
                switch (runtime->rate) {
                case 22050:
@@ -303,7 +302,6 @@ static void uni_player_set_channel_status(struct uniperif *player,
                player->stream_settings.iec958.status[3 + (n * 4)] << 24;
                SET_UNIPERIF_CHANNEL_STA_REGN(player, n, status);
        }
-       mutex_unlock(&player->ctrl_lock);
 
        /* Update the channel status */
        if (player->ver < SND_ST_UNIPERIF_VERSION_UNI_PLR_TOP_1_0)
@@ -365,8 +363,10 @@ static int uni_player_prepare_iec958(struct uniperif *player,
 
        SET_UNIPERIF_CTRL_ZERO_STUFF_HW(player);
 
+       mutex_lock(&player->ctrl_lock);
        /* Update the channel status */
        uni_player_set_channel_status(player, runtime);
+       mutex_unlock(&player->ctrl_lock);
 
        /* Clear the user validity user bits */
        SET_UNIPERIF_USER_VALIDITY_VALIDITY_LR(player, 0);
@@ -598,7 +598,6 @@ static int uni_player_ctl_iec958_put(struct snd_kcontrol *kcontrol,
        iec958->status[1] = ucontrol->value.iec958.status[1];
        iec958->status[2] = ucontrol->value.iec958.status[2];
        iec958->status[3] = ucontrol->value.iec958.status[3];
-       mutex_unlock(&player->ctrl_lock);
 
        spin_lock_irqsave(&player->irq_lock, flags);
        if (player->substream && player->substream->runtime)
@@ -608,6 +607,8 @@ static int uni_player_ctl_iec958_put(struct snd_kcontrol *kcontrol,
                uni_player_set_channel_status(player, NULL);
 
        spin_unlock_irqrestore(&player->irq_lock, flags);
+       mutex_unlock(&player->ctrl_lock);
+
        return 0;
 }