soc-pcm.c (de4fb176622d54a82ea3ceb7362392aaf5ff0b5a) soc-pcm.c (fb6d679fee95d272c0a94912c4e534146823ee89)
1// SPDX-License-Identifier: GPL-2.0+
2//
3// soc-pcm.c -- ALSA SoC PCM
4//
5// Copyright 2005 Wolfson Microelectronics PLC.
6// Copyright 2005 Openedhand Ltd.
7// Copyright (C) 2010 Slimlogic Ltd.
8// Copyright (C) 2010 Texas Instruments Inc.

--- 32 unchanged lines hidden (view full) ---

41 lockdep_assert_held(&(rtd)->card->pcm_mutex)
42
43static inline void snd_soc_dpcm_stream_lock_irq(struct snd_soc_pcm_runtime *rtd,
44 int stream)
45{
46 snd_pcm_stream_lock_irq(snd_soc_dpcm_get_substream(rtd, stream));
47}
48
1// SPDX-License-Identifier: GPL-2.0+
2//
3// soc-pcm.c -- ALSA SoC PCM
4//
5// Copyright 2005 Wolfson Microelectronics PLC.
6// Copyright 2005 Openedhand Ltd.
7// Copyright (C) 2010 Slimlogic Ltd.
8// Copyright (C) 2010 Texas Instruments Inc.

--- 32 unchanged lines hidden (view full) ---

41 lockdep_assert_held(&(rtd)->card->pcm_mutex)
42
43static inline void snd_soc_dpcm_stream_lock_irq(struct snd_soc_pcm_runtime *rtd,
44 int stream)
45{
46 snd_pcm_stream_lock_irq(snd_soc_dpcm_get_substream(rtd, stream));
47}
48
49#define snd_soc_dpcm_stream_lock_irqsave(rtd, stream, flags) \
50 snd_pcm_stream_lock_irqsave(snd_soc_dpcm_get_substream(rtd, stream), flags)
49#define snd_soc_dpcm_stream_lock_irqsave_nested(rtd, stream, flags) \
50 snd_pcm_stream_lock_irqsave_nested(snd_soc_dpcm_get_substream(rtd, stream), flags)
51
52static inline void snd_soc_dpcm_stream_unlock_irq(struct snd_soc_pcm_runtime *rtd,
53 int stream)
54{
55 snd_pcm_stream_unlock_irq(snd_soc_dpcm_get_substream(rtd, stream));
56}
57
58#define snd_soc_dpcm_stream_unlock_irqrestore(rtd, stream, flags) \

--- 1150 unchanged lines hidden (view full) ---

1209 return -EINVAL;
1210 }
1211 if (fe_substream->pcm->nonatomic && !be_substream->pcm->nonatomic) {
1212 dev_warn(be->dev, "%s: FE is nonatomic but BE is not, forcing BE as nonatomic\n",
1213 __func__);
1214 be_substream->pcm->nonatomic = 1;
1215 }
1216
51
52static inline void snd_soc_dpcm_stream_unlock_irq(struct snd_soc_pcm_runtime *rtd,
53 int stream)
54{
55 snd_pcm_stream_unlock_irq(snd_soc_dpcm_get_substream(rtd, stream));
56}
57
58#define snd_soc_dpcm_stream_unlock_irqrestore(rtd, stream, flags) \

--- 1150 unchanged lines hidden (view full) ---

1209 return -EINVAL;
1210 }
1211 if (fe_substream->pcm->nonatomic && !be_substream->pcm->nonatomic) {
1212 dev_warn(be->dev, "%s: FE is nonatomic but BE is not, forcing BE as nonatomic\n",
1213 __func__);
1214 be_substream->pcm->nonatomic = 1;
1215 }
1216
1217 dpcm = kzalloc(sizeof(struct snd_soc_dpcm), GFP_ATOMIC);
1217 dpcm = kzalloc(sizeof(struct snd_soc_dpcm), GFP_KERNEL);
1218 if (!dpcm)
1219 return -ENOMEM;
1220
1221 dpcm->be = be;
1222 dpcm->fe = fe;
1223 be->dpcm[stream].runtime = fe->dpcm[stream].runtime;
1224 dpcm->state = SND_SOC_DPCM_LINK_STATE_NEW;
1225 snd_soc_dpcm_stream_lock_irq(fe, stream);

--- 37 unchanged lines hidden (view full) ---

1263 break;
1264 }
1265}
1266
1267/* disconnect a BE and FE */
1268void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream)
1269{
1270 struct snd_soc_dpcm *dpcm, *d;
1218 if (!dpcm)
1219 return -ENOMEM;
1220
1221 dpcm->be = be;
1222 dpcm->fe = fe;
1223 be->dpcm[stream].runtime = fe->dpcm[stream].runtime;
1224 dpcm->state = SND_SOC_DPCM_LINK_STATE_NEW;
1225 snd_soc_dpcm_stream_lock_irq(fe, stream);

--- 37 unchanged lines hidden (view full) ---

1263 break;
1264 }
1265}
1266
1267/* disconnect a BE and FE */
1268void dpcm_be_disconnect(struct snd_soc_pcm_runtime *fe, int stream)
1269{
1270 struct snd_soc_dpcm *dpcm, *d;
1271 LIST_HEAD(deleted_dpcms);
1271
1272 snd_soc_dpcm_mutex_assert_held(fe);
1273
1274 snd_soc_dpcm_stream_lock_irq(fe, stream);
1275 for_each_dpcm_be_safe(fe, stream, dpcm, d) {
1276 dev_dbg(fe->dev, "ASoC: BE %s disconnect check for %s\n",
1277 stream ? "capture" : "playback",
1278 dpcm->be->dai_link->name);
1279
1280 if (dpcm->state != SND_SOC_DPCM_LINK_STATE_FREE)
1281 continue;
1282
1283 dev_dbg(fe->dev, "freed DSP %s path %s %s %s\n",
1284 stream ? "capture" : "playback", fe->dai_link->name,
1285 stream ? "<-" : "->", dpcm->be->dai_link->name);
1286
1287 /* BEs still alive need new FE */
1288 dpcm_be_reparent(fe, dpcm->be, stream);
1289
1272
1273 snd_soc_dpcm_mutex_assert_held(fe);
1274
1275 snd_soc_dpcm_stream_lock_irq(fe, stream);
1276 for_each_dpcm_be_safe(fe, stream, dpcm, d) {
1277 dev_dbg(fe->dev, "ASoC: BE %s disconnect check for %s\n",
1278 stream ? "capture" : "playback",
1279 dpcm->be->dai_link->name);
1280
1281 if (dpcm->state != SND_SOC_DPCM_LINK_STATE_FREE)
1282 continue;
1283
1284 dev_dbg(fe->dev, "freed DSP %s path %s %s %s\n",
1285 stream ? "capture" : "playback", fe->dai_link->name,
1286 stream ? "<-" : "->", dpcm->be->dai_link->name);
1287
1288 /* BEs still alive need new FE */
1289 dpcm_be_reparent(fe, dpcm->be, stream);
1290
1290 dpcm_remove_debugfs_state(dpcm);
1291
1292 list_del(&dpcm->list_be);
1291 list_del(&dpcm->list_be);
1292 list_move(&dpcm->list_fe, &deleted_dpcms);
1293 }
1294 snd_soc_dpcm_stream_unlock_irq(fe, stream);
1295
1296 while (!list_empty(&deleted_dpcms)) {
1297 dpcm = list_first_entry(&deleted_dpcms, struct snd_soc_dpcm,
1298 list_fe);
1293 list_del(&dpcm->list_fe);
1299 list_del(&dpcm->list_fe);
1300 dpcm_remove_debugfs_state(dpcm);
1294 kfree(dpcm);
1295 }
1301 kfree(dpcm);
1302 }
1296 snd_soc_dpcm_stream_unlock_irq(fe, stream);
1297}
1298
1299/* get BE for DAI widget and stream */
1300static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card,
1301 struct snd_soc_dapm_widget *widget, int stream)
1302{
1303 struct snd_soc_pcm_runtime *be;
1304 struct snd_soc_dapm_widget *w;

--- 784 unchanged lines hidden (view full) ---

2089 int ret = 0;
2090
2091 for_each_dpcm_be(fe, stream, dpcm) {
2092 struct snd_pcm_substream *be_substream;
2093
2094 be = dpcm->be;
2095 be_substream = snd_soc_dpcm_get_substream(be, stream);
2096
1303}
1304
1305/* get BE for DAI widget and stream */
1306static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card,
1307 struct snd_soc_dapm_widget *widget, int stream)
1308{
1309 struct snd_soc_pcm_runtime *be;
1310 struct snd_soc_dapm_widget *w;

--- 784 unchanged lines hidden (view full) ---

2095 int ret = 0;
2096
2097 for_each_dpcm_be(fe, stream, dpcm) {
2098 struct snd_pcm_substream *be_substream;
2099
2100 be = dpcm->be;
2101 be_substream = snd_soc_dpcm_get_substream(be, stream);
2102
2097 snd_soc_dpcm_stream_lock_irqsave(be, stream, flags);
2103 snd_soc_dpcm_stream_lock_irqsave_nested(be, stream, flags);
2098
2099 /* is this op for this BE ? */
2100 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
2101 goto next;
2102
2103 dev_dbg(be->dev, "ASoC: trigger BE %s cmd %d\n",
2104 be->dai_link->name, cmd);
2105

--- 920 unchanged lines hidden ---
2104
2105 /* is this op for this BE ? */
2106 if (!snd_soc_dpcm_be_can_update(fe, be, stream))
2107 goto next;
2108
2109 dev_dbg(be->dev, "ASoC: trigger BE %s cmd %d\n",
2110 be->dai_link->name, cmd);
2111

--- 920 unchanged lines hidden ---