diff options
author | U. Artie Eoff <ullysses.a.eoff@intel.com> | 2015-07-28 13:29:56 -0700 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2015-07-29 19:37:26 +0200 |
commit | 342e84490574cbb2a9c5b1d0886a112ad2bcf4d7 (patch) | |
tree | 39b96490d0d103e54602c3bb8d202f386b934c28 /sound | |
parent | 2d1cb7f658fb9c3ba8f9dab8aca297d4dfdec835 (diff) | |
download | linux-342e84490574cbb2a9c5b1d0886a112ad2bcf4d7.tar.gz linux-342e84490574cbb2a9c5b1d0886a112ad2bcf4d7.tar.bz2 linux-342e84490574cbb2a9c5b1d0886a112ad2bcf4d7.zip |
ALSA: hda - Fix race between PM ops and HDA init/probe
PM ops could be triggered before HDA is done initializing
and cause PM to set HDA controller to D3Hot. This can result
in "CORB reset timeout#2, CORBRP = 65535" and "no codecs
initialized". Additionally, PM ops can be triggered before
azx_probe_continue finishes (async probe). This can result
in a NULL deref kernel crash.
To fix this, avoid PM ops if !chip->running.
Signed-off-by: U. Artie Eoff <ullysses.a.eoff@intel.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/hda/hda_intel.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 735bdcb04ce8..c38c68f57938 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -867,7 +867,7 @@ static int azx_suspend(struct device *dev) chip = card->private_data; hda = container_of(chip, struct hda_intel, chip); - if (chip->disabled || hda->init_failed) + if (chip->disabled || hda->init_failed || !chip->running) return 0; bus = azx_bus(chip); @@ -902,7 +902,7 @@ static int azx_resume(struct device *dev) chip = card->private_data; hda = container_of(chip, struct hda_intel, chip); - if (chip->disabled || hda->init_failed) + if (chip->disabled || hda->init_failed || !chip->running) return 0; if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL @@ -1027,7 +1027,7 @@ static int azx_runtime_idle(struct device *dev) return 0; if (!power_save_controller || !azx_has_pm_runtime(chip) || - azx_bus(chip)->codec_powered) + azx_bus(chip)->codec_powered || !chip->running) return -EBUSY; return 0; |