Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4557c305 authored by Jeeja KP's avatar Jeeja KP Committed by Mark Brown
Browse files

ASoC: Intel: Skylake: Add support for active suspend



Some of the usecases can be marked as 'ignore_suspend' by
machine. For these on suspend we should keep audio controller
ON by saving the state and not suspending the device

For this we need to maintain a counter for these streams and be
active on suspend when such a stream is opened.

Signed-off-by: default avatarJeeja KP <jeeja.kp@intel.com>
Signed-off-by: default avatarVinod Koul <vinod.koul@intel.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 820f339f
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -109,6 +109,31 @@ static enum hdac_ext_stream_type skl_get_host_stream_type(struct hdac_ext_bus *e
		return HDAC_EXT_STREAM_TYPE_COUPLED;
}

/*
 * check if the stream opened is marked as ignore_suspend by machine, if so
 * then enable suspend_active refcount
 *
 * The count supend_active does not need lock as it is used in open/close
 * and suspend context
 */
static void skl_set_suspend_active(struct snd_pcm_substream *substream,
					 struct snd_soc_dai *dai, bool enable)
{
	struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev);
	struct snd_soc_dapm_widget *w;
	struct skl *skl = ebus_to_skl(ebus);

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		w = dai->playback_widget;
	else
		w = dai->capture_widget;

	if (w->ignore_suspend && enable)
		skl->supend_active++;
	else if (w->ignore_suspend && !enable)
		skl->supend_active--;
}

static int skl_pcm_open(struct snd_pcm_substream *substream,
		struct snd_soc_dai *dai)
{
@@ -146,6 +171,7 @@ static int skl_pcm_open(struct snd_pcm_substream *substream,

	dev_dbg(dai->dev, "stream tag set in dma params=%d\n",
				 dma_params->stream_tag);
	skl_set_suspend_active(substream, dai, true);
	snd_pcm_set_sync(substream);

	return 0;
@@ -257,6 +283,7 @@ static void skl_pcm_close(struct snd_pcm_substream *substream,
	 * dma_params
	 */
	snd_soc_dai_set_dma_data(dai, substream, NULL);
	skl_set_suspend_active(substream, dai, false);

	kfree(dma_params);
}
+26 −2
Original line number Diff line number Diff line
@@ -169,16 +169,40 @@ static int skl_suspend(struct device *dev)
{
	struct pci_dev *pci = to_pci_dev(dev);
	struct hdac_ext_bus *ebus = pci_get_drvdata(pci);
	struct skl *skl  = ebus_to_skl(ebus);

	/*
	 * Do not suspend if streams which are marked ignore suspend are
	 * running, we need to save the state for these and continue
	 */
	if (skl->supend_active) {
		pci_save_state(pci);
		pci_disable_device(pci);
		return 0;
	} else {
		return _skl_suspend(ebus);
	}
}

static int skl_resume(struct device *dev)
{
	struct pci_dev *pci = to_pci_dev(dev);
	struct hdac_ext_bus *ebus = pci_get_drvdata(pci);
	struct skl *skl  = ebus_to_skl(ebus);
	int ret;

	return _skl_resume(ebus);
	/*
	 * resume only when we are not in suspend active, otherwise need to
	 * restore the device
	 */
	if (skl->supend_active) {
		pci_restore_state(pci);
		ret = pci_enable_device(pci);
	} else {
		ret = _skl_resume(ebus);
	}

	return ret;
}
#endif /* CONFIG_PM_SLEEP */

+2 −0
Original line number Diff line number Diff line
@@ -70,6 +70,8 @@ struct skl {
	struct list_head ppl_list;

	const char *fw_name;

	int supend_active;
};

#define skl_to_ebus(s)	(&(s)->ebus)