diff options
author | Takashi Iwai <tiwai@suse.de> | 2008-10-31 17:24:01 +0100 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2008-10-31 17:24:01 +0100 |
commit | afecd78cd2ec81512d6ec451906f71d9671a0b3b (patch) | |
tree | cac6cba97ae90c4e509f05686de22aafc8264862 /sound/pci/hda/hda_intel.c | |
parent | Merge branch 'topic/fix/hda' into topic/hda (diff) | |
parent | ALSA: hda - Add digital-mic for ALC269 auto-probe mode (diff) | |
download | linux-afecd78cd2ec81512d6ec451906f71d9671a0b3b.tar.xz linux-afecd78cd2ec81512d6ec451906f71d9671a0b3b.zip |
Merge branch 'topic/fix/hda' into topic/hda
Diffstat (limited to 'sound/pci/hda/hda_intel.c')
-rw-r--r-- | sound/pci/hda/hda_intel.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index a13169cc95a2..614be2ec806f 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -45,6 +45,7 @@ #include <linux/slab.h> #include <linux/pci.h> #include <linux/mutex.h> +#include <linux/reboot.h> #include <sound/core.h> #include <sound/initval.h> #include "hda_codec.h" @@ -397,6 +398,9 @@ struct azx { /* for pending irqs */ struct work_struct irq_pending_work; + + /* reboot notifier (for mysterious hangup problem at power-down) */ + struct notifier_block reboot_notifier; }; /* driver types */ @@ -1903,12 +1907,36 @@ static int azx_resume(struct pci_dev *pci) /* + * reboot notifier for hang-up problem at power-down + */ +static int azx_halt(struct notifier_block *nb, unsigned long event, void *buf) +{ + struct azx *chip = container_of(nb, struct azx, reboot_notifier); + azx_stop_chip(chip); + return NOTIFY_OK; +} + +static void azx_notifier_register(struct azx *chip) +{ + chip->reboot_notifier.notifier_call = azx_halt; + register_reboot_notifier(&chip->reboot_notifier); +} + +static void azx_notifier_unregister(struct azx *chip) +{ + if (chip->reboot_notifier.notifier_call) + unregister_reboot_notifier(&chip->reboot_notifier); +} + +/* * destructor */ static int azx_free(struct azx *chip) { int i; + azx_notifier_unregister(chip); + if (chip->initialized) { azx_clear_irq_pending(chip); for (i = 0; i < chip->num_streams; i++) @@ -2272,6 +2300,7 @@ static int __devinit azx_probe(struct pci_dev *pci, pci_set_drvdata(pci, card); chip->running = 1; power_down_all_codecs(chip); + azx_notifier_register(chip); dev++; return err; |