From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Gustaw Lewandowski Date: Tue, 30 Oct 2018 14:46:08 +0100 Subject: [PATCH] Revert "ASoC: tdf8532: add crit sections" Reverted patch introduces memory leak in tdf8532_resume and causes other problems with audio functionality. Change-Id: I186554e03c6ccfde90bedc5ee31ad5c670b7c079 Tracked-On: OAM-71677 Signed-off-by: Gustaw Lewandowski --- sound/soc/codecs/tdf8532.c | 93 ++++++++++++++++---------------------- sound/soc/codecs/tdf8532.h | 1 - 2 files changed, 39 insertions(+), 55 deletions(-) diff --git a/sound/soc/codecs/tdf8532.c b/sound/soc/codecs/tdf8532.c index 9fc73b6..02e63f9 100644 --- a/sound/soc/codecs/tdf8532.c +++ b/sound/soc/codecs/tdf8532.c @@ -21,11 +21,8 @@ #include #include #include -#include #include "tdf8532.h" -static DEFINE_MUTEX(tdf8532_lock); - static int __tdf8532_build_pkt(struct tdf8532_priv *dev_data, va_list valist, u8 *payload) { @@ -213,12 +210,11 @@ static int tdf8532_wait_state(struct tdf8532_priv *dev_data, u8 req_state, static int tdf8532_start_play(struct tdf8532_priv *tdf8532) { - int ret = 0; + int ret; - mutex_lock(&tdf8532_lock); ret = tdf8532_amp_write(tdf8532, SET_CLK_STATE, CLK_CONNECT); if (ret < 0) - goto out; + return ret; ret = tdf8532_amp_write(tdf8532, SET_CHNL_ENABLE, CHNL_MASK(tdf8532->channels)); @@ -226,22 +222,22 @@ static int tdf8532_start_play(struct tdf8532_priv *tdf8532) if (ret >= 0) ret = tdf8532_wait_state(tdf8532, STATE_PLAY, ACK_TIMEOUT); -out: - if (ret >= 0) - tdf8532->powered = 1; - mutex_unlock(&tdf8532_lock); return ret; } + static int tdf8532_stop_play(struct tdf8532_priv *tdf8532) { - int ret = 0; + int ret; + ret = tdf8532_amp_write(tdf8532, SET_CHNL_DISABLE, CHNL_MASK(tdf8532->channels)); if (ret < 0) goto out; - tdf8532_wait_state(tdf8532, STATE_STBY, ACK_TIMEOUT); + ret = tdf8532_wait_state(tdf8532, STATE_STBY, ACK_TIMEOUT); + if (ret < 0) + goto out; ret = tdf8532_amp_write(tdf8532, SET_CLK_STATE, CLK_DISCONNECT); if (ret < 0) @@ -253,17 +249,30 @@ static int tdf8532_stop_play(struct tdf8532_priv *tdf8532) return ret; } -static int tdf8532_dai_trigger_pb(struct snd_pcm_substream *substream, int cmd, + +static int tdf8532_dai_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { int ret = 0; struct snd_soc_component *component = dai->component; struct tdf8532_priv *tdf8532 = snd_soc_component_get_drvdata(component); - dev_dbg(component->dev, "%s: cmd:%d substream:%d\n", __func__, cmd, - substream->stream); - if (cmd == SNDRV_PCM_TRIGGER_START && !tdf8532->powered) + dev_dbg(component->dev, "%s: cmd = %d\n", __func__, cmd); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + case SNDRV_PCM_TRIGGER_RESUME: ret = tdf8532_start_play(tdf8532); + break; + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_STOP: + /* WA on unexpected codec down during S3 + SNDRV_PCM_TRIGGER_STOP fails so skip set ret */ + tdf8532_stop_play(tdf8532); + break; + } return ret; } @@ -272,48 +281,25 @@ static int tdf8532_mute(struct snd_soc_dai *dai, int mute) { struct snd_soc_component *component = dai->component; struct tdf8532_priv *tdf8532 = snd_soc_component_get_drvdata(component); - int ret; - - dev_dbg(component->dev, "%s mute:%d\n", __func__, mute); - mutex_lock(&tdf8532_lock); - ret = tdf8532_amp_write(tdf8532, (mute)?SET_CHNL_MUTE:SET_CHNL_UNMUTE, - CHNL_MASK(CHNL_MAX)); - mutex_unlock(&tdf8532_lock); - return ret; -} - -static const struct snd_soc_dai_ops tdf8532_dai_ops_pb = { - .trigger = tdf8532_dai_trigger_pb, - .digital_mute = tdf8532_mute, -}; - -static int tdf8532_resume(struct snd_soc_component *component) -{ - int ret; - struct tdf8532_priv *tdf8532 = snd_soc_component_get_drvdata(component); - u8 cur_state = STATE_NONE; - struct get_dev_status_repl *status_repl = NULL; dev_dbg(component->dev, "%s\n", __func__); - mutex_lock(&tdf8532_lock); - ret = tdf8532_get_state(tdf8532, &status_repl); - mutex_unlock(&tdf8532_lock); - if (ret < 0) - goto out; - cur_state = status_repl->state; - dev_dbg(component->dev, "%s cur_state:%d\n", __func__, cur_state); - if (cur_state < STATE_PLAY) - tdf8532_start_play(tdf8532); -out: - return 0; + if (mute) + return tdf8532_amp_write(tdf8532, SET_CHNL_MUTE, + CHNL_MASK(CHNL_MAX)); + else + return tdf8532_amp_write(tdf8532, SET_CHNL_UNMUTE, + CHNL_MASK(CHNL_MAX)); } -static const struct snd_soc_component_driver soc_component_tdf8532 = { - .resume = tdf8532_resume, +static const struct snd_soc_dai_ops tdf8532_dai_ops = { + .trigger = tdf8532_dai_trigger, + .digital_mute = tdf8532_mute, }; -static struct snd_soc_dai_driver tdf8532_dai_pb[] = { +static struct snd_soc_component_driver soc_component_tdf8532; + +static struct snd_soc_dai_driver tdf8532_dai[] = { { .name = "tdf8532-hifi", .playback = { @@ -323,7 +309,7 @@ static struct snd_soc_dai_driver tdf8532_dai_pb[] = { .rates = SNDRV_PCM_RATE_48000, .formats = SNDRV_PCM_FMTBIT_S16_LE, }, - .ops = &tdf8532_dai_ops_pb, + .ops = &tdf8532_dai_ops, } }; @@ -346,12 +332,11 @@ static int tdf8532_i2c_probe(struct i2c_client *i2c, dev_data->i2c = i2c; dev_data->pkt_id = 0; dev_data->channels = 4; - dev_data->powered = 0; i2c_set_clientdata(i2c, dev_data); ret = devm_snd_soc_register_component(&i2c->dev, &soc_component_tdf8532, - tdf8532_dai_pb, ARRAY_SIZE(tdf8532_dai_pb)); + tdf8532_dai, ARRAY_SIZE(tdf8532_dai)); if (ret != 0) { dev_err(&i2c->dev, "Failed to register codec: %d\n", ret); goto out; diff --git a/sound/soc/codecs/tdf8532.h b/sound/soc/codecs/tdf8532.h index 0f35407..39353a0 100644 --- a/sound/soc/codecs/tdf8532.h +++ b/sound/soc/codecs/tdf8532.h @@ -96,7 +96,6 @@ struct tdf8532_priv { struct i2c_client *i2c; u8 channels; u8 pkt_id; - u8 powered:1; }; #endif -- https://clearlinux.org