diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-11-20 09:03:38 +0100 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-11-20 09:03:38 +0100 |
commit | 90accd6fabf9b2fa2705945a4c601877a75d43bf (patch) | |
tree | d393cb54f0228b1313139e4e14adf4f5cf236b59 /sound/pci/hda/hda_intel.c | |
parent | b43d196c4d3fe46d6dda7c987c47792612b80b1b (diff) | |
parent | ee2f6cc7f9ea2542ad46070ed62ba7aa04d08871 (diff) |
Merge branch 'linus' into x86/memory-corruption-check
Diffstat (limited to 'sound/pci/hda/hda_intel.c')
-rw-r--r-- | sound/pci/hda/hda_intel.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 9f316c1b279..35722ec920c 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 */ @@ -1979,12 +1983,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++) @@ -2158,7 +2186,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, } chip->addr = pci_resource_start(pci, 0); - chip->remap_addr = ioremap_nocache(chip->addr, pci_resource_len(pci,0)); + chip->remap_addr = pci_ioremap_bar(pci, 0); if (chip->remap_addr == NULL) { snd_printk(KERN_ERR SFX "ioremap error\n"); err = -ENXIO; @@ -2348,6 +2376,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; |