summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2021-11-15 08:59:44 +0100
committerTakashi Iwai <tiwai@suse.de>2021-11-15 10:22:15 +0100
commit4f66a9ef37d3c09917a1edc065ff68b895e0b163 (patch)
treee54454a2ef067df3865b7e1e3778157575e156f9
parentLinux 5.16-rc1 (diff)
downloadlinux-4f66a9ef37d3c09917a1edc065ff68b895e0b163.tar.xz
linux-4f66a9ef37d3c09917a1edc065ff68b895e0b163.zip
ALSA: hda: intel: More comprehensive PM runtime setup for controller driver
Currently we haven't explicitly enable and allow/forbid the runtime PM at the probe and the remove phases of HD-audio controller driver, and this was the reason of a GPF mentioned in the commit e81478bbe7a1 ("ALSA: hda: fix general protection fault in azx_runtime_idle"); namely, even after the resources are released, the runtime PM might be still invoked by the bound graphics driver during the remove of the controller driver. Although we've fixed it by clearing the drvdata reference, it'd be also better to cover the runtime PM issue more properly. This patch adds a few more pm_runtime_*() calls at the probe and the remove time for setting and cleaning up the runtime PM. Particularly, now more explicitly pm_runtime_enable() and _disable() get called as well as pm_runtime_forbid() call at the remove callback, so that a use-after-free should be avoided. Reported-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Tested-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Link: https://lore.kernel.org/r/20211110210307.1172004-1-kai.vehmanen@linux.intel.com Link: https://lore.kernel.org/r/20211115075944.6972-1-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/pci/hda/hda_intel.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index fe51163f2d82..45e85180048c 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1347,8 +1347,14 @@ static void azx_free(struct azx *chip)
if (hda->freed)
return;
- if (azx_has_pm_runtime(chip) && chip->running)
+ if (azx_has_pm_runtime(chip) && chip->running) {
pm_runtime_get_noresume(&pci->dev);
+ pm_runtime_disable(&pci->dev);
+ pm_runtime_set_suspended(&pci->dev);
+ pm_runtime_forbid(&pci->dev);
+ pm_runtime_dont_use_autosuspend(&pci->dev);
+ }
+
chip->running = 0;
azx_del_card_list(chip);
@@ -2322,6 +2328,8 @@ static int azx_probe_continue(struct azx *chip)
if (azx_has_pm_runtime(chip)) {
pm_runtime_use_autosuspend(&pci->dev);
pm_runtime_allow(&pci->dev);
+ pm_runtime_set_active(&pci->dev);
+ pm_runtime_enable(&pci->dev);
pm_runtime_put_autosuspend(&pci->dev);
}