Re: HDA, power saving and recording

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 2023-05-15 5:33 PM, Takashi Iwai wrote:
On Mon, 15 May 2023 16:49:48 +0200,
Amadeusz Sławiński wrote:

...

I think there are two problems:

1. After probe codec is powered down
(https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/sound/pci/hda/hda_codec.c#n833),
even though according to power management it is still running

I guess it's in the auto-suspend state, so it's still not suspended
but the device itself is active, while the usage count is 0.

That's fine, and I thought my second patch handling it.  That is, if
the usage count is 0 and the device is not suspended, it should return
-EAGAIN and make the caller retry with the full power up.
The code path is with CALL_RUN_FUNC() macro in hdac_regmap.c, and with
-EAGAIN return value, it tries snd_hdac_power_up_pm() and call the
function again.

2. When stream is started before first suspend, resume function
doesn't run and it is a function which syncs cached registers. By
resume function I mean
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/sound/pci/hda/hda_codec.c#n2899
which calls snd_hda_regmap_sync() or through in case of the platform I
test it on codec->patch_ops.resume(codec) -> alc269_resume, which also
calls snd_hda_regmap_sync().

It's also expected, per se.  Since it's been not suspended, it assumes
that the value got already written, and no resume is needed.


After reading this conversation few times I came to conclusion that codec device should be kept up as long as its runtime_status=0 (RPM_ACTIVE), regardless if usage_count is 0 or not. Basically, in autosuspend case usage_count and runtime_status for the device are both 0 so, if we are not ignoring the former by calling pm_runtime_get_if_in_use() then we end up caching the writes during the autosuspend period - period when the device is no longer used but there is still some time left before it's suspended.


--- a/sound/hda/hdac_device.c
+++ b/sound/hda/hdac_device.c
@@ -611,7 +611,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_power_up_pm);
 int snd_hdac_keep_power_up(struct hdac_device *codec)
 {
        if (!atomic_inc_not_zero(&codec->in_pm)) {
-               int ret = pm_runtime_get_if_in_use(&codec->dev);
+               int ret = pm_runtime_get_if_active(&codec->dev, true);
                if (!ret)
                        return -1;
                if (ret < 0)


Results for the above look good.




[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Pulse Audio]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux