Re: [PATCH 2/2] ALSA: hda/cs8409: Prevent pops and clicks during reboot

From: Vitaly Rodionov
Date: Thu Aug 26 2021 - 06:56:32 EST


On 26/08/2021 11:49 am, Takashi Iwai wrote:
On Thu, 26 Aug 2021 08:03:45 +0200,
Takashi Iwai wrote:
On Wed, 25 Aug 2021 20:04:05 +0200,
Vitaly Rodionov wrote:
Actually when codec is suspended and we do reboot from UI, then sometimes we
see suspend() calls in kernel log and no pops, but sometimes

we still have no suspend() on reboot and we hear pops. But when we do reboot
from command line: > sudo reboot  then we always have pops and no suspend()
called.

Then we have added extra logging and we can see that on reboot codec somehow
getting resume() call and we run jack detect on resume that causing pops.
Hm, it's interesting who triggers the runtime resume.

We were thinking about possible solution for that and we would propose some
changes in generic code hda_bind.c:

static void hda_codec_driver_shutdown(struct device *dev) { +   if (codec->
patch_ops.suspend) +      codec->patch_ops.suspend(codec);
snd_hda_codec_shutdown(dev_to_hda_codec(dev)); +  hda_codec_driver_remove
(dev_to_hda_codec(dev)); }
Sorry, it's no-no. The suspend can't be called unconditionally, and
the driver unbind must not be called in the callback itself.

Does the patch below work instead?
Sorry there was a typo. A bit more revised patch is below.


Takashi

Hi Takashi,

Thanks a lot for quick response. I have tested previous patch and it did not fix an issue, as suspend() was not called.

Now I will test new revised patch and let you know ASAP.

I am adding some extra logging, unfortunately on reboot these messages are missing from kernel log, however I managed to capture reboot screen

and I will attach an image where last messages shown.

Thanks,

Vitaly


--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1383,14 +1383,17 @@ static void azx_free(struct azx *chip)
hda->freed = 1;
}
-static int azx_dev_disconnect(struct snd_device *device)
+static void __azx_disconnect(struct azx *chip)
{
- struct azx *chip = device->device_data;
struct hdac_bus *bus = azx_bus(chip);
chip->bus.shutdown = 1;
cancel_work_sync(&bus->unsol_work);
+}
+static int azx_dev_disconnect(struct snd_device *device)
+{
+ __azx_disconnect(device->device_data);
return 0;
}
@@ -2356,8 +2359,10 @@ static void azx_shutdown(struct pci_dev *pci)
if (!card)
return;
chip = card->private_data;
- if (chip && chip->running)
+ if (chip && chip->running) {
+ __azx_disconnect(chip);
azx_shutdown_chip(chip);
+ }
}
/* PCI IDs */