Commit Graph

484 Commits

Author SHA1 Message Date
Ranjani Sridharan e123036be3
ASoC: soc-pcm: test if a BE can be prepared
In the BE hw_params configuration, the existing code checks if any of the
existing FEs are prepared, running, paused or suspended - and skips the
configuration in those cases. This allows multiple calls of hw_params
which the ALSA state machine supports.

This check is not handled for the prepare stage, which can lead to the
same BE being prepared multiple times. This patch adds a check similar to
that of the hw_params, with the main difference being that the suspended
state is allowed: the ALSA state machine allows a transition from
suspended to prepared with hw_params skipped.

This problem was detected on Intel IPC4/SoundWire devices, where the BE
dailink .prepare stage is used to configure the SoundWire stream with a
bank switch. Multiple .prepare calls lead to conflicts with the .trigger
operation with IPC4 configurations. This problem was not detected earlier
on Intel devices, HDaudio BE dailinks detect that the link is already
prepared and skip the configuration, and for IPC3 devices there is no BE
trigger.

Link: https://github.com/thesofproject/sof/issues/7596
Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com
Link: https://lore.kernel.org/r/20230517185731.487124-1-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org
2023-05-19 02:31:14 +09:00
Kuninori Morimoto 38e42f6d6c
ASoC: expand snd_soc_dpcm_mutex_lock/unlock()
soc-pcm.c has snd_soc_dpcm_mutex_lock/unlock(),
but other files can't use it because it is static function.

It requests snd_soc_pcm_runtime as parameter (A), but sometimes we
want to use it by snd_soc_card (B).

(A)	static inline void snd_soc_dpcm_mutex_lock(struct snd_soc_pcm_runtime *rtd)
	{
		mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
	}			   ^^^^^^^^^

(B)	mutex_lock_nested(&card->pcm_mutex, card->pcm_subclass);
			   ^^^^

We want to use it with both "rtd" and "card" for dapm lock/unlock.
To enable it, this patch uses _Generic macro.

This patch makes snd_soc_dpcm_mutex_{un}lock() global function, and use it on
each files.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87bkk1x3ud.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2023-04-17 12:57:25 +01:00
Kuninori Morimoto 7ddc7f91be
ASoC: soc.h: clarify Codec2Codec params
snd_soc_dai_link has params/num_params, but it is unclear that
params for what. This patch clarify it is params for Codec2Codec.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87o7o5c2lk.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2023-04-05 12:16:36 +01:00
Mark Brown 461b56f261
ASoC: Merge fixes
So they can be used as a basis for new work.
2023-03-30 00:14:00 +01:00
Kuninori Morimoto 0d3a5178c2
ASoC: soc-pcm.c: remove indirect runtime copy
substream->runtime will be attached when substream was opened
at snd_pcm_attach_substream(). When it uses DPCM,
FE substream->runtime is attached, but BE substream->runtime is not.
Thus, we are copying FE substream->runtime to BE.

But, we are copyig FE substream->runtime to FE dpcm->runtime first (A),
and copy it to BE dpcm->runtime (B), and copy it to
BE substream->runtime (C).

	static int dpcm_fe_dai_open(...) {
		...
(A)		fe->dpcm[stream].runtime = fe_substream->runtime;
		...
	}

	static int dpcm_be_connect(...) {
		...
(B)		be->dpcm[stream].runtime = fe->dpcm[stream].runtime;
		...
	}

	int dpcm_be_dai_startup(...) {
		...
(C)		be_substream->runtime = be->dpcm[stream].runtime;
		...
	}

It is too roundabout and troublesome.
OTOH, it is directly copying fe_substream->runtime at dpcm_be_reparent()
without using be->dpcm[stream].runtime.

	static void dpcm_be_reparent(...)
	{
		...
		for_each_dpcm_fe(be, stream, dpcm) {
			...
=>			be_substream->runtime = fe_substream->runtime;
			break;
		}
	}

This patch removes indirect copying.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87v8je64dh.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2023-03-14 13:58:57 +00:00
Shengjiu Wang 083a25b18d
ASoC: soc-pcm: fix hw->formats cleared by soc_pcm_hw_init() for dpcm
The hw->formats may be set by snd_dmaengine_pcm_refine_runtime_hwparams()
in component's startup()/open(), but soc_pcm_hw_init() will init
hw->formats in dpcm_runtime_setup_fe() after component's startup()/open(),
which causes the valuable hw->formats to be cleared.

So need to store the hw->formats before initialization, then restore
it after initialization.

Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Link: https://lore.kernel.org/r/1678346017-3660-1-git-send-email-shengjiu.wang@nxp.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2023-03-14 13:30:16 +00:00
Claudiu Beznea 54fc4b72b6
ASoC: soc-pcm: add option to start DMA after DAI
Add option to start DMA component after DAI trigger. This is done
by filling the new struct snd_soc_component_driver::start_dma_last.

Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
Link: https://lore.kernel.org/r/20230228110145.3770525-2-claudiu.beznea@microchip.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2023-02-28 13:58:48 +00:00
Kuninori Morimoto e15ff262e2
ASoC: soc-pcm.c: use helper function
Current ASoC has many helper function.
This patch use it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Link: https://lore.kernel.org/r/87fsbrea25.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2023-01-31 11:05:10 +00:00
Ranjani Sridharan 5edcf2a3aa
ASoC: soc-pcm: Export widget_in_list()
Export the widget_in_list() function to be used by other modules.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://lore.kernel.org/r/20230127120031.10709-3-peter.ujfalusi@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2023-01-27 12:13:59 +00:00
Chancel Liu 1da681e528
ASoC: soc-pcm.c: Clear DAIs parameters after stream_active is updated
DAIs parameters should be cleared if there's no active stream. Before,
we implemented it in soc_pcm_hw_free() by detecting stream_active. If
the running stream is the last active stream, we're going to clear
parameters.

However it will cause DAIs parameters never be cleared if there're
more than one stream. For example, we have stream1 and stream2 about
to stop. stream2 executes soc_pcm_hw_free() before stream1 executes
soc_pcm_close(). At the moment, stream2 should clear DAIs parameters.
Since stream_active is not yet updated by stream1 in soc_pcm_close(),
stream2 will not clear DAIs parameters. In result both stream1 and
stream2 don't clear the parameters.

This patch moves DAIs parameters cleanup after stream_active is
updated.

Signed-off-by: Chancel Liu <chancel.liu@nxp.com>
Link: https://lore.kernel.org/r/20221128060950.3540845-1-chancel.liu@nxp.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-12-07 20:05:16 +00:00
Mark Brown aeb2e9c4ee
ASoC: Merge up fixes
Merge the fixes branch up so we can apply further AMD work.
2022-11-29 12:55:51 +00:00
Srinivasa Rao Mandadapu db8f91d424
ASoC: soc-pcm: Add NULL check in BE reparenting
Add NULL check in dpcm_be_reparent API, to handle
kernel NULL pointer dereference error.
The issue occurred in fuzzing test.

Signed-off-by: Srinivasa Rao Mandadapu <quic_srivasam@quicinc.com>
Link: https://lore.kernel.org/r/1669098673-29703-1-git-send-email-quic_srivasam@quicinc.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-11-22 12:23:00 +00:00
Richard Fitzgerald 39bd801d69
ASoC: soc-pcm: Don't zero TDM masks in __soc_pcm_open()
The DAI tx_mask and rx_mask are set by snd_soc_dai_set_tdm_slot()
and used by later code that depends on the TDM settings. So
__soc_pcm_open() should not be obliterating those mask values.

The code in __soc_pcm_hw_params() uses these masks to calculate the
active channels so that only the AIF_IN/AIF_OUT widgets for the
active TDM slots are enabled. The zeroing of the masks in
__soc_pcm_open() disables this functionality so all AIF widgets
were enabled even for channels that are not assigned to a TDM slot.

Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Fixes: 2e5894d737 ("ASoC: pcm: Add support for DAI multicodec")
Link: https://lore.kernel.org/r/20221104132213.121847-1-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-11-10 21:01:48 +00:00
Kuninori Morimoto 25106550f1
ASoC: soc-dpcm.h: remove snd_soc_dpcm::hw_param
Current soc-pcm.c is coping fe hw_param to dpcm->hw_param (A),
fixup it (B), and copy it to be (C).

	int dpcm_be_dai_hw_params(...)
	{
		...
		for_each_dpcm_be(fe, stream, dpcm) {
			...
			/* copy params for each dpcm */
(A)			memcpy(&dpcm->hw_params, &fe->dpcm[stream].hw_params, ...) ;

			/* perform any hw_params fixups */
(B)			ret = snd_soc_link_be_hw_params_fixup(be, &dpcm->hw_params);
			...

			/* copy the fixed-up hw params for BE dai */
(C)			memcpy(&be->dpcm[stream].hw_params, &dpcm->hw_params, ...);
			...
		}
		...
	}

But here, (1) it is coping hw_params without caring stream (Playback/Capture),
(2) we can get same value from be. We don't need to have dpcm->hw_params.
This patch removes it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Reviewed-by: Amadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
Link: https://lore.kernel.org/r/87v8ogsl6h.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-10-19 13:05:34 +01:00
Kuninori Morimoto 3989ade2d1
ASoC: soc.h: remove num_cpus/codecs
Current rtd has both dai_link pointer (A) and num_cpus/codecs (B).

(A)	rtd->dai_link	= dai_link;
(B)	rtd->num_cpus	= dai_link->num_cpus;
(B)	rtd->num_codecs	= dai_link->num_codecs;

But, we can get num_cpus/codecs (B) via dai_link (A).
This means we don't need to keep num_cpus/codecs on rtd.
This patch removes these.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87sfkmv9n3.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-09-20 12:19:30 +01:00
Kuninori Morimoto 6932b20d4f
ASoC: soc-pcm.c: check fe condition at out of loop
Current dpcm_add_paths() is checking fe condition in loop (= A),
but fe condition (X) is not related to the loop (B).

(X)	static int dpcm_add_paths(fe, stream, ...)
	{
		...
(B)		for_each_dapm_widgets(list, i, widget) {
			...
(A)			if (!fe->dpcm[stream].runtime && !fe->fe_compr)
				continue;
			...
		}
		...
	}

This patch checks fe condition at out of loop

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87pmgi4dz4.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-09-05 13:09:07 +01:00
Kuninori Morimoto 041107289c
ASoC: soc-pcm.c: add soc_pcm_ret()
Current soc-pcm.c has many similar code for error case.
This patch adds soc_pcm_ret() and share the code and error message.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87r10y4dzb.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-09-05 13:09:06 +01:00
Kuninori Morimoto 10d5d8cbf6
ASoC: soc-pcm.c: remove unnecessary codec2codec_close_delayed_work()
commit 4bf2e385aa ("ASoC: core: Init pcm runtime work early to
avoid warnings") has added generic close_delayed_work() which checks
close_delayed_work_func

	static void close_delayed_work(...) {
		...
=>		if (rtd->close_delayed_work_func)
			rtd->close_delayed_work_func(rtd);
	}

So, we don't need to have NULL function for Codec2Codec.

=>	static void codec2codec_close_delayed_work()
	{
		/*
		 * Currently nothing to do for c2c links
		 * Since c2c links are internal nodes in the DAPM graph and
		 * don't interface with the outside world or application layer
		 * we don't have to do any special handling on close.
		 */
	}

	int soc_new_pcm(...)
	{
		...
		if (rtd->dai_link->params)
=>			rtd->close_delayed_work_func = codec2codec_close_delayed_work;
		else
			rtd->close_delayed_work_func = snd_soc_close_delayed_work;
		...
	}

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87sfle4dzk.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-09-05 13:09:05 +01:00
Kuninori Morimoto 6bbabd2880
ASoC: soc-pcm.c: call __soc_pcm_close() in soc_pcm_close()
commit b7898396f4 ("ASoC: soc-pcm: Fix and cleanup DPCM locking")
added __soc_pcm_close() for non-lock version of soc_pcm_close().
But soc_pcm_close() is not using it. It is no problem, but confusable.

	static int __soc_pcm_close(...)
	{
=>		return soc_pcm_clean(rtd, substream, 0);
	}

	static int soc_pcm_close(...)
	{
		...
		snd_soc_dpcm_mutex_lock(rtd);
=>		soc_pcm_clean(rtd, substream, 0);
		snd_soc_dpcm_mutex_unlock(rtd);
		return 0;
	}

This patch use it.

Fixes: b7898396f4 ("ASoC: soc-pcm: Fix and cleanup DPCM locking")
Cc: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87czctgg3w.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-08-25 17:58:30 +01:00
Kuninori Morimoto 4d45d944e8
ASoC: soc-pcm.c: summarize related settings at soc_new_pcm()
soc_new_pcm() sets pcm->no_device_suspend, but it sets other pcm->xxx
at the same function with different timing.
pcm->no_device_suspend setup timing has no effect. This patch tidyup it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87bksdgflq.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-08-22 14:07:21 +01:00
Takashi Iwai 754590651c
ASoC: DPCM: Don't pick up BE without substream
When DPCM tries to add valid BE connections at dpcm_add_paths(), it
doesn't check whether the picked BE actually supports for the given
stream direction.  Due to that, when an asymmetric BE stream is
present, it picks up wrongly and this may result in a NULL dereference
at a later point where the code assumes the existence of a
corresponding BE substream.

This patch adds the check for the presence of the substream for the
target BE for avoiding the problem above.

Note that we have already some fix for non-existing BE substream at
commit 6246f283d5 ("ASoC: dpcm: skip missing substream while
applying symmetry").  But the code path we've hit recently is rather
happening before the previous fix.  So this patch tries to fix at
picking up a BE instead of parsing BE lists.

Fixes: bbf7d3b1c4 ("ASoC: soc-pcm: align BE 'atomicity' with that of the FE")
Reported-by: Alex Natalsson <harmoniesworlds@gmail.com>
Cc: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Cc: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://lore.kernel.org/r/CADs9LoPZH_D+eJ9qjTxSLE5jGyhKsjMN7g2NighZ16biVxsyKw@mail.gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20220801170510.26582-1-tiwai@suse.de
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-08-05 14:20:51 +01:00
Pierre-Louis Bossart 4ccf0949cd
ASoC: soc-pcm: demote warnings on non-atomic BE connection
When an FE, typically non-atomic, is connected to an atomic BE, we
force the BE as non-atomic. There's no reason to throw a warning, this
is a perfectly fine configuration and a conversion that's required
by-design.

This removes the unconditional warnings such as

[   12.054213]  iDisp1: dpcm_be_connect: FE is nonatomic but BE is not, forcing BE as nonatomic
[   12.074693]  iDisp2: dpcm_be_connect: FE is nonatomic but BE is not, forcing BE as nonatomic
[   12.096612]  iDisp3: dpcm_be_connect: FE is nonatomic but BE is not, forcing BE as nonatomic
[   12.118637]  iDisp4: dpcm_be_connect: FE is nonatomic but BE is not, forcing BE as nonatomic
[   12.140660]  dmic01: dpcm_be_connect: FE is nonatomic but BE is not, forcing BE as nonatomic
[   12.147521]  dmic16k: dpcm_be_connect: FE is nonatomic but BE is not, forcing BE as nonatomic

and demotes them to dev_dbg(), as suggested in review comments.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Link: https://lore.kernel.org/r/20220708200641.26923-1-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-07-12 13:45:07 +01:00
Pierre-Louis Bossart f4d6aca0c8
ASoC: soc-pcm: fix BE transition for TRIGGER_START
A obvious editing mistake caught with a cppcheck warning

sound/soc/soc-pcm.c:2132:8: style: Variable 'ret' is reassigned a
value before the old one has been used. [redundantAssignment]
   ret = soc_pcm_trigger(be_substream, cmd);
       ^
sound/soc/soc-pcm.c:2126:9: note: ret is assigned
    ret = soc_pcm_trigger(be_substream,
        ^
sound/soc/soc-pcm.c:2129:9: note: ret is assigned
    ret = soc_pcm_trigger(be_substream,
        ^

Fixes: 374b50e234 ('ASoC: soc-pcm: improve BE transition for TRIGGER_START')
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://lore.kernel.org/r/20220520210615.607229-1-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-05-23 14:52:59 +01:00
Pierre-Louis Bossart 374b50e234
ASoC: soc-pcm: improve BE transition for TRIGGER_START
When the BE was in PAUSED state, the correct trigger is PAUSE_RELEASE.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Link: https://lore.kernel.org/r/20220406190056.233481-3-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-04-19 16:33:52 +01:00
Pierre-Louis Bossart 9995c1d096
ASoC: soc-pcm: improve BE transition for PAUSE_RELEASE
Commit 3aa1e96a2b ("ASoC: soc-pcm: fix BE handling of PAUSE_RELEASE")
did not modify the existing logic and kept the same logic for the following
transition

    play FE1    -> BE state is START
    pause FE1   -> BE state is PAUSED
    play FE2    -> BE state is START
    stop FE2    -> BE state is STOP <<< !!
    release FE1 -> BE state is START
    stop FE1    -> BE state is STOP

At the time it was identified by reviewers that a better solution
might consist in

    play FE1    -> BE state is START
    pause FE1   -> BE state is PAUSED
    play FE2    -> BE state is START
    stop FE2    -> BE state is PAUSE <<< !!
    release FE1 -> BE state is START
    stop FE1    -> BE state is STOP

This patch suggest a transition to PAUSE when all the 'active' streams
are paused. This would allow for a more consistent resource management
for platforms where PAUSE and STOP are handled differently.

To track the special case of an FE going from PAUSE_PUSH to STOP, we
add a state variable for each FE context. This 'fe_pause' boolean is
set on PAUSE_PUSH and cleared on either PAUSE_RELEASE and STOP
triggers.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Link: https://lore.kernel.org/r/20220406190056.233481-2-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-04-19 16:33:51 +01:00
Christophe JAILLET fb6d679fee
ASoC: soc-pcm: use GFP_KERNEL when the code is sleepable
At the kzalloc() call in dpcm_be_connect(), there is no spin lock involved.
It's merely protected by card->pcm_mutex, instead.  The spinlock is applied
at the later call with snd_soc_pcm_stream_lock_irq() only for the list
manipulations.  (See it's *_irq(), not *_irqsave(); that means the context
being sleepable at that point.)  So, we can use GFP_KERNEL safely there.

This patch revert commit d8a9c6e1f6 ("ASoC: soc-pcm: use GFP_ATOMIC for
dpcm structure") which is no longer needed since commit b7898396f4
("ASoC: soc-pcm: Fix and cleanup DPCM locking").

Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Link: https://lore.kernel.org/r/e740f1930843060e025e3c0f17ec1393cfdafb26.1648757961.git.christophe.jaillet@wanadoo.fr
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-04-04 14:25:39 +01:00
Takashi Iwai 9f620684c1
ASoC: soc-pcm: Move debugfs removal out of spinlock
The recent fix for DPCM locking also covered the loop in
dpcm_be_disconnect() with the FE stream lock.  This caused an
unexpected side effect, thought: calling debugfs_remove_recursive() in
the spinlock may lead to lockdep splats as the code there assumes the
SOFTIRQ-safe context.

For avoiding the problem, this patch changes the disconnection
procedure to two phases: at first, the matching entries are removed
from the linked list, then the resources are freed outside the lock.

Fixes: b7898396f4 ("ASoC: soc-pcm: Fix and cleanup DPCM locking")
Reported-and-tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20220119155249.26754-3-tiwai@suse.de
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-01-28 15:59:18 +00:00
Takashi Iwai 3c75c0ea5d
ASoC: soc-pcm: Fix DPCM lockdep warning due to nested stream locks
The recent change for DPCM locking caused spurious lockdep warnings.
Actually the warnings are false-positive, as those are triggered due
to the nested stream locks for FE and BE.  Since both locks belong to
the same lock class, lockdep sees it as if a deadlock.

For fixing this, we need to take PCM stream locks for BE with the
nested lock primitives.  Since currently snd_pcm_stream_lock*() helper
assumes only the top-level single locking, a new helper function
snd_pcm_stream_lock_irqsave_nested() is defined for a single-depth
nested lock, which is now used in the BE DAI trigger that is always
performed inside a FE stream lock.

Fixes: b2ae806630 ("ASoC: soc-pcm: serialize BE triggers")
Reported-and-tested-by: Hans de Goede <hdegoede@redhat.com>
Reported-and-tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Link: https://lore.kernel.org/r/73018f3c-9769-72ea-0325-b3f8e2381e30@redhat.com
Link: https://lore.kernel.org/alsa-devel/9a0abddd-49e9-872d-2f00-a1697340f786@samsung.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20220119155249.26754-2-tiwai@suse.de
Signed-off-by: Mark Brown <broonie@kernel.org>
2022-01-28 15:59:16 +00:00
Pierre-Louis Bossart 3aa1e96a2b
ASoC: soc-pcm: fix BE handling of PAUSE_RELEASE
A BE connected to more than one FE, e.g. in a mixer case, can go
through the following transitions.

play FE1    -> BE state is START
pause FE1   -> BE state is PAUSED
play FE2    -> BE state is START
stop FE2    -> BE state is STOP (see note [1] below)
release FE1 -> BE state is START
stop FE1    -> BE state is STOP

play FE1    -> BE state is START
pause FE1   -> BE state is PAUSED
play FE2    -> BE state is START
release FE1 -> BE state is START
stop FE2    -> BE state is START
stop FE1    -> BE state is STOP

play FE1    -> BE state is START
play FE2    -> BE state is START (no change)
pause FE1   -> BE state is START (no change)
pause FE2   -> BE state is PAUSED
release FE1 -> BE state is START
release FE2 -> BE state is START (no change)
stop FE1    -> BE state is START (no change)
stop FE2    -> BE state is STOP

The existing code for PAUSE_RELEASE only allows for the case where the
BE is paused, which clearly would not work in the sequences above.

Extend the allowed states to restart the BE when PAUSE_RELEASE is
received, and increase the refcount if the BE is already in START.

[1] the existing logic does not move the BE state back to PAUSED when
the FE2 is stopped. This patch does not change the logic; it would be
painful to keep a history of changes on the FE side, the state machine
is already rather complicated with transitions based on the last BE
state and the trigger type.

Reported-by: Bard Liao <bard.liao@intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Link: https://lore.kernel.org/r/20211207173745.15850-7-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-12-14 17:15:48 +00:00
Pierre-Louis Bossart 848aedfdc6
ASoC: soc-pcm: test refcount before triggering
On start/pause_release/resume, when more than one FE is connected to
the same BE, it's possible that the trigger is sent more than
once. This is not desirable, we only want to trigger a BE once, which
is straightforward to implement with a refcount.

For stop/pause/suspend, the problem is more complicated: the check
implemented in snd_soc_dpcm_can_be_free_stop() may fail due to a
conceptual deadlock when we trigger the BE before the FE. In this
case, the FE states have not yet changed, so there are corner cases
where the TRIGGER_STOP is never sent - the dual case of start where
multiple triggers might be sent.

This patch suggests an unconditional trigger in all cases, without
checking the FE states, using a refcount protected by the BE PCM
stream lock.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Link: https://lore.kernel.org/r/20211207173745.15850-6-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-12-14 17:15:47 +00:00
Takashi Iwai b2ae806630
ASoC: soc-pcm: serialize BE triggers
When more than one FE is connected to a BE, e.g. in a mixing use case,
the BE can be triggered multiple times when the FE are opened/started
concurrently. This race condition is problematic in the case of
SoundWire BE dailinks, and this is not desirable in a general
case.

This patch relies on the existing BE PCM lock, which takes atomicity into
account. The locking model assumes that all interactions start with
the FE, so that there is no deadlock between FE and BE locks.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
[test, checkpatch fix and clarification of commit message by plbossart]
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Link: https://lore.kernel.org/r/20211207173745.15850-5-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-12-14 17:15:46 +00:00
Takashi Iwai b7898396f4
ASoC: soc-pcm: Fix and cleanup DPCM locking
The existing locking for DPCM has several issues
a) a confusing mix of card->mutex and card->pcm_mutex.
b) a dpcm_lock spinlock added inconsistently and on paths that could
be recursively taken. The use of irqsave/irqrestore was also overkill.

The suggested model is:

1) The pcm_mutex is the top-most protection of BE links in the FE. The
pcm_mutex is applied always on either the top PCM callbacks or the
external call from DAPM, not taken in the internal functions.

2) the FE stream lock is taken in higher levels before invoking
dpcm_be_dai_trigger()

3) when adding and deleting a BE, both the pcm_mutex and FE stream
lock are taken.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
[clarification of commit message by plbossart]
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Link: https://lore.kernel.org/r/20211207173745.15850-4-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-12-14 17:15:45 +00:00
Pierre-Louis Bossart bbf7d3b1c4
ASoC: soc-pcm: align BE 'atomicity' with that of the FE
Since the flow for DPCM is based on taking a lock for the FE first, we
need to make sure during the connection between a BE and an FE that
they both use the same 'atomicity', otherwise we may sleep in atomic
context.

If the FE is nonatomic, this patch forces the BE to be nonatomic as
well. That should have no negative impact since the BE 'inherits' the
FE properties.

However, if the FE is atomic and the BE is not, then the configuration
is flagged as invalid.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
[ removed FE stream lock by tiwai ]
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Link: https://lore.kernel.org/r/20211207173745.15850-3-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-12-14 17:15:44 +00:00
Pierre-Louis Bossart d8a9c6e1f6
ASoC: soc-pcm: use GFP_ATOMIC for dpcm structure
We allocate a structure in dpcm_be_connect(), which may be called in
atomic context. Using GFP_KERNEL is not quite right, we have to use
GFP_ATOMIC to prevent the allocator from sleeping.

Suggested-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Link: https://lore.kernel.org/r/20211207173745.15850-2-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-12-14 17:15:42 +00:00
Kuninori Morimoto dd894f4caf
ASoC: soc-pcm: tidyup soc_pcm_pointer()'s delay update method
No driver directly updates runtime->delay in .pointer.
This patch cleanups its method.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87zgq4wnkx.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-11-29 12:19:45 +00:00
Kuninori Morimoto 403f830e7a
ASoC: soc-component: add snd_soc_pcm_component_delay()
Current soc-pcm.c :: soc_pcm_pointer() is assuming that
component driver might update runtime->delay silently in
snd_soc_pcm_component_pointer() (= A).

	static snd_pcm_uframes_t soc_pcm_pointer(...)
	{
		...

		/* clearing the previous total delay */
=>		runtime->delay = 0;

(A)		offset = snd_soc_pcm_component_pointer(substream);

		/* base delay if assigned in pointer callback */
=>		delay = runtime->delay;
		...
	}

1) The behavior that ".pointer callback secretly updates
   runtime->delay" is strange and confusable.

2) Current snd_soc_pcm_component_pointer() uses 1st found component's
   .pointer callback only, thus it is no problem for now.
   But runtime->delay might be overwrote if it adjusted to multiple
   components in the future.

3) Component delay is updated at .pointer callback timing (secretly).
   But some components which doesn't have .pointer callback might want
   to increase runtime->delay for some reasons.

We already have .delay function for DAI, but not have for Component.
This patch adds new snd_soc_pcm_component_delay() for it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/874k8cy25t.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-11-29 12:19:41 +00:00
Kuninori Morimoto 8544f08c81
ASoC: soc-dai: update snd_soc_dai_delay() to snd_soc_pcm_dai_delay()
Current soc_pcm_pointer() is manually calculating
both CPU-DAI's   max delay (= A)
and  Codec-DAI's max delay (= B).

	static snd_pcm_uframes_t soc_pcm_pointer(...)
	{
		...
 ^		for_each_rtd_cpu_dais(rtd, i, cpu_dai)
(A)			cpu_delay = max(cpu_delay, ...);
 v		delay += cpu_delay;

 ^		for_each_rtd_codec_dais(rtd, i, codec_dai)
(B)			codec_delay = max(codec_delay, ...);
 v		delay += codec_delay;

		runtime->delay = delay;
		...
	}

Current soc_pcm_pointer() and the total delay calculating
is not readable / difficult to understand.

This patch update snd_soc_dai_delay() to snd_soc_pcm_dai_delay(),
and calcule both CPU/Codec delay in one function.

Link: https://lore.kernel.org/r/87fszl4yrq.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/875yssy25z.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-11-29 12:19:40 +00:00
Kuninori Morimoto 86e4aef6c9
ASoC: soc-pcm: tidyup soc_pcm_hw_clean() - step2
DAI active count is not exchanged during for_each_rtd_dais()
loops. We don't need to keep snd_soc_dai_stream_active() as
"active" on soc_pcm_hw_clean(). This patch avoid verbose code.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87ilxvt7e6.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-10-18 13:56:36 +01:00
Kuninori Morimoto 121966d03b
ASoC: soc-pcm: tidyup soc_pcm_hw_clean() - step1
soc_pcm_hw_clean() is using "continue" during for_each_rtd_dais(),
but it is very verbose. This patch cleanup it.

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87k0ibt7ej.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-10-18 13:56:35 +01:00
Pierre-Louis Bossart 9609cfcda0
ASoC: soc-pcm: restore mixer functionality
Recent changes in soc-pcm completely broke basic support for mixers on
Intel systems: the filters on BE states prevent the connection of a
second mixer input while the back-end is already active.

Rather than reverting the changes, which would be problematic for
Tegra systems, this patch suggests an additional filter which will
only apply to Tegra systems. This is a temporary solution which will
have to be revisited - additional issues have been reported with DPCM.

Fixes: 0c25db3f76 ('ASoC: soc-pcm: Don't reconnect an already active BE')
Suggested-by: Sameer Pujar <spujar@nvidia.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://lore.kernel.org/r/20211004212141.193136-1-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-10-07 19:20:00 +01:00
Ranjani Sridharan d1a7af0979
AsoC: dapm: export a couple of functions
Export a couple of DAPM functions that can be used by
ASoC drivers to determine connected widgets when a PCM
is started.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://lore.kernel.org/r/20210927120517.20505-6-peter.ujfalusi@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-10-01 20:48:23 +01:00
Sameer Pujar 0c25db3f76
ASoC: soc-pcm: Don't reconnect an already active BE
In some cases, multiple FE components have the same BE component in their
respective DPCM paths. One such example would be a mixer component, which
can receive two or more inputs and sends a mixed output. In such cases,
to avoid reconfiguration of already active DAI (mixer output DAI in this
case), check the BE stream state to filter out the redundancy.

In summary, allow connection of BE if the respective current stream state
is either NEW or CLOSED.

Signed-off-by: Sameer Pujar <spujar@nvidia.com>
Link: https://lore.kernel.org/r/1631551342-25469-2-git-send-email-spujar@nvidia.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-09-20 13:31:27 +01:00
Mark Brown 3202e2f5fa
ASoC: Revert PCM trigger changes
These have turned up some issues in further testing.

Signed-off-by: Mark Brown <broonie@kernel.org>
2021-08-30 12:15:15 +01:00
Pierre-Louis Bossart 6479f75886
ASoC: soc-pcm: test refcount before triggering
On start/pause_release/resume, when more than one FE is connected to
the same BE, it's possible that the trigger is sent more than
once. This is not desirable, we only want to trigger a BE once, which
is straightforward to implement with a refcount.

For stop/pause/suspend, the problem is more complicated: the check
implemented in snd_soc_dpcm_can_be_free_stop() may fail due to a
conceptual deadlock when we trigger the BE before the FE. In this
case, the FE states have not yet changed, so there are corner cases
where the TRIGGER_STOP is never sent - the dual case of start where
multiple triggers might be sent.

This patch suggests an unconditional trigger in all cases, without
checking the FE states, using a refcount protected by a spinlock.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Message-Id: <20210817164054.250028-3-pierre-louis.bossart@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-08-26 17:42:08 +01:00
Pierre-Louis Bossart 0c75fc7193
ASoC: soc-pcm: protect BE dailink state changes in trigger
When more than one FE is connected to a BE, e.g. in a mixing use case,
the BE can be triggered multiple times when the FE are opened/started
concurrently. This race condition is problematic in the case of
SoundWire BE dailinks, and this is not desirable in a general
case. The code carefully checks when the BE can be stopped or
hw_free'ed, but the trigger code does not use any mutual exclusion.

Fix by using the same spinlock already used to check FE states, and
set the state before the trigger. In case of errors,  the initial
state will be restored.

This patch does not change how the triggers are handled, it only makes
sure the states are handled in critical sections.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Message-Id: <20210817164054.250028-2-pierre-louis.bossart@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-08-26 17:42:07 +01:00
Mark Brown ddaa1ed52c
Merge some cs42l42 patches into asoc-5.15 2021-08-06 01:46:24 +01:00
Kuninori Morimoto 9bdc573d84
ASoC: soc-pcm: cleanup cppcheck warning at dpcm_runtime_setup_be_chan()
This patch cleanups below cppcheck warning.

sound/soc/soc-pcm.c:1624:30: style: The scope of the variable 'codec_stream' can be reduced. [variableScope]
  struct snd_soc_pcm_stream *codec_stream;
                             ^

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87o8aozf28.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-07-27 13:14:50 +01:00
Kuninori Morimoto 7931df9bf0
ASoC: soc-pcm: cleanup cppcheck warning at dpcm_be_is_active()
This patch cleanups below cppcheck warning.

sound/soc/soc-pcm.c:1305:30: style: The scope of the variable 'widget' can be reduced. [variableScope]
 struct snd_soc_dapm_widget *widget;
                             ^

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87pmv4zf2c.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-07-27 13:14:47 +01:00
Kuninori Morimoto 940a1f4357
ASoC: soc-pcm: cleanup cppcheck warning at soc_get_playback_capture()
This patch cleanups below cppcheck warning.

sound/soc/soc-pcm.c:2578:22: style: The scope of the variable 'codec_dai' can be reduced. [variableScope]
 struct snd_soc_dai *codec_dai;
                     ^
sound/soc/soc-pcm.c:2580:6: style: The scope of the variable 'stream' can be reduced. [variableScope]
 int stream;
     ^

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87r1fkzf2g.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-07-27 13:14:46 +01:00
Kuninori Morimoto 33be10b563
ASoC: soc-pcm: cleanup cppcheck warning at soc_pcm_components_close()
This patch cleanups below cppcheck warning.

sound/soc/soc-pcm.c:631:9: style: The scope of the variable 'r' can be reduced. [variableScope]
 int i, r, ret = 0;
        ^

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87sg00zf2l.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2021-07-27 13:14:45 +01:00