diff options
author | Takashi Iwai <tiwai@suse.de> | 2015-03-05 17:21:32 +0100 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2015-03-13 15:28:58 +0100 |
commit | b2a0bafa758256442e04d1f34d6d0746b846d23d (patch) | |
tree | 97f3ada5d1e4aced0254f856bf819bc9dca57b89 | |
parent | d56db741b8e688a0b9d4d5bb9caa11dfcb7c0b08 (diff) |
ALSA: hda - Use shutdown driver ops instead of reboot notifier
The driver shutdown ops is simpler than registering reboot notifier
manually. There should be no functional change by this -- the codec
driver calls its own callback while the bus driver just calls
azx_stop() like before.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | sound/pci/hda/hda_bind.c | 10 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.c | 18 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.h | 1 | ||||
-rw-r--r-- | sound/pci/hda/hda_controller.c | 26 | ||||
-rw-r--r-- | sound/pci/hda/hda_controller.h | 6 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 16 | ||||
-rw-r--r-- | sound/pci/hda/hda_tegra.c | 16 |
7 files changed, 36 insertions, 57 deletions
diff --git a/sound/pci/hda/hda_bind.c b/sound/pci/hda/hda_bind.c index a49bc45c2ea5..1f40ce3c1696 100644 --- a/sound/pci/hda/hda_bind.c +++ b/sound/pci/hda/hda_bind.c @@ -9,6 +9,7 @@ #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" @@ -142,6 +143,14 @@ static int hda_codec_driver_remove(struct device *dev) 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) { @@ -150,6 +159,7 @@ int __hda_codec_driver_register(struct hda_codec_driver *drv, const char *name, 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); } diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 6fecf57c8d7c..3e4fb7a8fdcb 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -4942,24 +4942,6 @@ static void cleanup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid) } /** - * 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 * @mout: hda_multi_out object diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index bf9efb7e1b9a..70851e6d5f10 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -563,7 +563,6 @@ extern const struct snd_pcm_chmap_elem snd_pcm_2_1_chmaps[]; * 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); diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c index cae50d5ffb81..b1143f22a0c2 100644 --- a/sound/pci/hda/hda_controller.c +++ b/sound/pci/hda/hda_controller.c @@ -27,7 +27,6 @@ #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" @@ -1972,30 +1971,5 @@ int azx_init_stream(struct azx *chip) } 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"); diff --git a/sound/pci/hda/hda_controller.h b/sound/pci/hda/hda_controller.h index 94c1a4719f7f..be1b7ded8d82 100644 --- a/sound/pci/hda/hda_controller.h +++ b/sound/pci/hda/hda_controller.h @@ -362,9 +362,6 @@ struct azx { /* 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 @@ -437,7 +434,4 @@ int azx_probe_codecs(struct azx *chip, unsigned int max_slots); 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 */ diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index dbc5a593da46..25668fde8480 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1066,8 +1066,6 @@ static int azx_free(struct azx *chip) azx_del_card_list(chip); - azx_notifier_unregister(chip); - hda->init_failed = 1; /* to be sure */ complete_all(&hda->probe_wait); @@ -1900,7 +1898,6 @@ static int azx_probe_continue(struct azx *chip) 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) @@ -1921,6 +1918,18 @@ static void azx_remove(struct pci_dev *pci) 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 */ @@ -2143,6 +2152,7 @@ static struct pci_driver azx_driver = { .id_table = azx_ids, .probe = azx_probe, .remove = azx_remove, + .shutdown = azx_shutdown, .driver = { .pm = AZX_PM_OPS, }, diff --git a/sound/pci/hda/hda_tegra.c b/sound/pci/hda/hda_tegra.c index 7586abe91dfb..2e4fd5c56d3b 100644 --- a/sound/pci/hda/hda_tegra.c +++ b/sound/pci/hda/hda_tegra.c @@ -290,8 +290,6 @@ static int hda_tegra_dev_free(struct snd_device *device) 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]); @@ -502,7 +500,6 @@ static int hda_tegra_probe(struct platform_device *pdev) goto out_free; chip->running = 1; - azx_notifier_register(chip); snd_hda_set_power_save(chip->bus, power_save * 1000); return 0; @@ -517,6 +514,18 @@ static int hda_tegra_remove(struct platform_device *pdev) 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", @@ -525,6 +534,7 @@ static struct platform_driver tegra_platform_hda = { }, .probe = hda_tegra_probe, .remove = hda_tegra_remove, + .shutdown = hda_tegra_shutdown, }; module_platform_driver(tegra_platform_hda); |