#include <linux/module.h>
 #include <linux/export.h>
 #include <linux/pm.h>
+#include <linux/pm_runtime.h>
 #include <sound/core.h>
 #include "hda_codec.h"
 #include "hda_local.h"
        return 0;
 }
 
+static void hda_codec_driver_shutdown(struct device *dev)
+{
+       struct hda_codec *codec = dev_to_hda_codec(dev);
+
+       if (!pm_runtime_suspended(dev) && codec->patch_ops.reboot_notify)
+               codec->patch_ops.reboot_notify(codec);
+}
+
 int __hda_codec_driver_register(struct hda_codec_driver *drv, const char *name,
                               struct module *owner)
 {
        drv->driver.bus = &snd_hda_bus_type;
        drv->driver.probe = hda_codec_driver_probe;
        drv->driver.remove = hda_codec_driver_remove;
+       drv->driver.shutdown = hda_codec_driver_shutdown;
        drv->driver.pm = &hda_codec_driver_pm;
        return driver_register(&drv->driver);
 }
 
        }
 }
 
-/**
- * snd_hda_bus_reboot_notify - call the reboot notifier of each codec
- * @bus: HD-audio bus
- */
-void snd_hda_bus_reboot_notify(struct hda_bus *bus)
-{
-       struct hda_codec *codec;
-
-       if (!bus)
-               return;
-       list_for_each_entry(codec, &bus->codec_list, list) {
-               if (hda_codec_is_power_on(codec) &&
-                   codec->patch_ops.reboot_notify)
-                       codec->patch_ops.reboot_notify(codec);
-       }
-}
-EXPORT_SYMBOL_GPL(snd_hda_bus_reboot_notify);
-
 /**
  * snd_hda_multi_out_dig_open - open the digital out in the exclusive mode
  * @codec: the HDA codec
 
  * Misc
  */
 void snd_hda_get_codec_name(struct hda_codec *codec, char *name, int namelen);
-void snd_hda_bus_reboot_notify(struct hda_bus *bus);
 void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg,
                                    unsigned int power_state);
 
 
 #include <linux/module.h>
 #include <linux/pm_runtime.h>
 #include <linux/slab.h>
-#include <linux/reboot.h>
 #include <sound/core.h>
 #include <sound/initval.h>
 #include "hda_controller.h"
 }
 EXPORT_SYMBOL_GPL(azx_init_stream);
 
-/*
- * 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);
-       snd_hda_bus_reboot_notify(chip->bus);
-       azx_stop_chip(chip);
-       return NOTIFY_OK;
-}
-
-void azx_notifier_register(struct azx *chip)
-{
-       chip->reboot_notifier.notifier_call = azx_halt;
-       register_reboot_notifier(&chip->reboot_notifier);
-}
-EXPORT_SYMBOL_GPL(azx_notifier_register);
-
-void azx_notifier_unregister(struct azx *chip)
-{
-       if (chip->reboot_notifier.notifier_call)
-               unregister_reboot_notifier(&chip->reboot_notifier);
-}
-EXPORT_SYMBOL_GPL(azx_notifier_unregister);
-
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Common HDA driver functions");
 
        /* for debugging */
        unsigned int last_cmd[AZX_MAX_CODECS];
 
-       /* reboot notifier (for mysterious hangup problem at power-down) */
-       struct notifier_block reboot_notifier;
-
 #ifdef CONFIG_SND_HDA_DSP_LOADER
        struct azx_dev saved_azx_dev;
 #endif
 int azx_codec_configure(struct azx *chip);
 int azx_init_stream(struct azx *chip);
 
-void azx_notifier_register(struct azx *chip);
-void azx_notifier_unregister(struct azx *chip);
-
 #endif /* __SOUND_HDA_CONTROLLER_H */
 
 
        azx_del_card_list(chip);
 
-       azx_notifier_unregister(chip);
-
        hda->init_failed = 1; /* to be sure */
        complete_all(&hda->probe_wait);
 
                goto out_free;
 
        chip->running = 1;
-       azx_notifier_register(chip);
        azx_add_card_list(chip);
        snd_hda_set_power_save(chip->bus, power_save * 1000);
        if (azx_has_pm_runtime(chip) || hda->use_vga_switcheroo)
                snd_card_free(card);
 }
 
+static void azx_shutdown(struct pci_dev *pci)
+{
+       struct snd_card *card = pci_get_drvdata(pci);
+       struct azx *chip;
+
+       if (!card)
+               return;
+       chip = card->private_data;
+       if (chip && chip->running)
+               azx_stop_chip(chip);
+}
+
 /* PCI IDs */
 static const struct pci_device_id azx_ids[] = {
        /* CPT */
        .id_table = azx_ids,
        .probe = azx_probe,
        .remove = azx_remove,
+       .shutdown = azx_shutdown,
        .driver = {
                .pm = AZX_PM_OPS,
        },
 
        int i;
        struct azx *chip = device->device_data;
 
-       azx_notifier_unregister(chip);
-
        if (chip->initialized) {
                for (i = 0; i < chip->num_streams; i++)
                        azx_stream_stop(chip, &chip->azx_dev[i]);
                goto out_free;
 
        chip->running = 1;
-       azx_notifier_register(chip);
        snd_hda_set_power_save(chip->bus, power_save * 1000);
 
        return 0;
        return snd_card_free(dev_get_drvdata(&pdev->dev));
 }
 
+static void hda_tegra_shutdown(struct platform_device *pdev)
+{
+       struct snd_card *card = dev_get_drvdata(&pdev->dev);
+       struct azx *chip;
+
+       if (!card)
+               return;
+       chip = card->private_data;
+       if (chip && chip->running)
+               azx_stop_chip(chip);
+}
+
 static struct platform_driver tegra_platform_hda = {
        .driver = {
                .name = "tegra-hda",
        },
        .probe = hda_tegra_probe,
        .remove = hda_tegra_remove,
+       .shutdown = hda_tegra_shutdown,
 };
 module_platform_driver(tegra_platform_hda);