Commit 436ec40e authored by Takashi Iwai's avatar Takashi Iwai
Browse files

Merge branch 'topic/pcm-device-suspend' into for-next



Pull the PCM suspend improvement / cleanup.
This moves the most of snd_pcm_suspend*() calls into PCM's own device
PM ops.  There should be no change from the functionality POV.

Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parents 053b0559 ce7f93e2
Loading
Loading
Loading
Loading
+8 −17
Original line number Diff line number Diff line
@@ -3924,15 +3924,12 @@ The scheme of the real suspend job is as follows.
2. Call :c:func:`snd_power_change_state()` with
   ``SNDRV_CTL_POWER_D3hot`` to change the power status.

3. Call :c:func:`snd_pcm_suspend_all()` to suspend the running
   PCM streams.

4. If AC97 codecs are used, call :c:func:`snd_ac97_suspend()` for
3. If AC97 codecs are used, call :c:func:`snd_ac97_suspend()` for
   each codec.

5. Save the register values if necessary.
4. Save the register values if necessary.

6. Stop the hardware if necessary.
5. Stop the hardware if necessary.

A typical code would be like:

@@ -3946,12 +3943,10 @@ A typical code would be like:
          /* (2) */
          snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
          /* (3) */
          snd_pcm_suspend_all(chip->pcm);
          /* (4) */
          snd_ac97_suspend(chip->ac97);
          /* (5) */
          /* (4) */
          snd_mychip_save_registers(chip);
          /* (6) */
          /* (5) */
          snd_mychip_stop_hardware(chip);
          return 0;
  }
@@ -3994,13 +3989,9 @@ A typical code would be like:
          return 0;
  }

As shown in the above, it's better to save registers after suspending
the PCM operations via :c:func:`snd_pcm_suspend_all()` or
:c:func:`snd_pcm_suspend()`. It means that the PCM streams are
already stopped when the register snapshot is taken. But, remember that
you don't have to restart the PCM stream in the resume callback. It'll
be restarted via trigger call with ``SNDRV_PCM_TRIGGER_RESUME`` when
necessary.
Note that, at the time this callback gets called, the PCM stream has
been already suspended via its own PM ops calling
:c:func:`snd_pcm_suspend_all()` internally.

OK, we have all callbacks now. Let's set them up. In the initialization
of the card, make sure that you can get the chip data from the card
+0 −1
Original line number Diff line number Diff line
@@ -614,7 +614,6 @@ static int snd_dw_hdmi_suspend(struct device *dev)
	struct snd_dw_hdmi *dw = dev_get_drvdata(dev);

	snd_power_change_state(dw->card, SNDRV_CTL_POWER_D3cold);
	snd_pcm_suspend_all(dw->pcm);

	return 0;
}
+1 −5
Original line number Diff line number Diff line
@@ -538,6 +538,7 @@ struct snd_pcm {
	void (*private_free) (struct snd_pcm *pcm);
	bool internal; /* pcm is for internal use only */
	bool nonatomic; /* whole PCM operations are in non-atomic context */
	bool no_device_suspend; /* don't invoke device PM suspend */
#if IS_ENABLED(CONFIG_SND_PCM_OSS)
	struct snd_pcm_oss oss;
#endif
@@ -581,13 +582,8 @@ int snd_pcm_stop(struct snd_pcm_substream *substream, snd_pcm_state_t status);
int snd_pcm_drain_done(struct snd_pcm_substream *substream);
int snd_pcm_stop_xrun(struct snd_pcm_substream *substream);
#ifdef CONFIG_PM
int snd_pcm_suspend(struct snd_pcm_substream *substream);
int snd_pcm_suspend_all(struct snd_pcm *pcm);
#else
static inline int snd_pcm_suspend(struct snd_pcm_substream *substream)
{
	return 0;
}
static inline int snd_pcm_suspend_all(struct snd_pcm *pcm)
{
	return 0;
+0 −4
Original line number Diff line number Diff line
@@ -380,10 +380,6 @@ static int i2sbus_suspend(struct macio_dev* dev, pm_message_t state)
	int err, ret = 0;

	list_for_each_entry(i2sdev, &control->list, item) {
		/* Notify Alsa */
		/* Suspend PCM streams */
		snd_pcm_suspend_all(i2sdev->sound.pcm);

		/* Notify codecs */
		list_for_each_entry(cii, &i2sdev->sound.codec_list, list) {
			err = 0;
+0 −1
Original line number Diff line number Diff line
@@ -757,7 +757,6 @@ static int aaci_do_suspend(struct snd_card *card)
{
	struct aaci *aaci = card->private_data;
	snd_power_change_state(card, SNDRV_CTL_POWER_D3cold);
	snd_pcm_suspend_all(aaci->pcm);
	return 0;
}

Loading