aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/pci/hda/hda_bind.c10
-rw-r--r--sound/pci/hda/hda_codec.c18
-rw-r--r--sound/pci/hda/hda_codec.h1
-rw-r--r--sound/pci/hda/hda_controller.c26
-rw-r--r--sound/pci/hda/hda_controller.h6
-rw-r--r--sound/pci/hda/hda_intel.c16
-rw-r--r--sound/pci/hda/hda_tegra.c16
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 @@
9#include <linux/module.h> 9#include <linux/module.h>
10#include <linux/export.h> 10#include <linux/export.h>
11#include <linux/pm.h> 11#include <linux/pm.h>
12#include <linux/pm_runtime.h>
12#include <sound/core.h> 13#include <sound/core.h>
13#include "hda_codec.h" 14#include "hda_codec.h"
14#include "hda_local.h" 15#include "hda_local.h"
@@ -142,6 +143,14 @@ static int hda_codec_driver_remove(struct device *dev)
142 return 0; 143 return 0;
143} 144}
144 145
146static void hda_codec_driver_shutdown(struct device *dev)
147{
148 struct hda_codec *codec = dev_to_hda_codec(dev);
149
150 if (!pm_runtime_suspended(dev) && codec->patch_ops.reboot_notify)
151 codec->patch_ops.reboot_notify(codec);
152}
153
145int __hda_codec_driver_register(struct hda_codec_driver *drv, const char *name, 154int __hda_codec_driver_register(struct hda_codec_driver *drv, const char *name,
146 struct module *owner) 155 struct module *owner)
147{ 156{
@@ -150,6 +159,7 @@ int __hda_codec_driver_register(struct hda_codec_driver *drv, const char *name,
150 drv->driver.bus = &snd_hda_bus_type; 159 drv->driver.bus = &snd_hda_bus_type;
151 drv->driver.probe = hda_codec_driver_probe; 160 drv->driver.probe = hda_codec_driver_probe;
152 drv->driver.remove = hda_codec_driver_remove; 161 drv->driver.remove = hda_codec_driver_remove;
162 drv->driver.shutdown = hda_codec_driver_shutdown;
153 drv->driver.pm = &hda_codec_driver_pm; 163 drv->driver.pm = &hda_codec_driver_pm;
154 return driver_register(&drv->driver); 164 return driver_register(&drv->driver);
155} 165}
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)
4942} 4942}
4943 4943
4944/** 4944/**
4945 * snd_hda_bus_reboot_notify - call the reboot notifier of each codec
4946 * @bus: HD-audio bus
4947 */
4948void snd_hda_bus_reboot_notify(struct hda_bus *bus)
4949{
4950 struct hda_codec *codec;
4951
4952 if (!bus)
4953 return;
4954 list_for_each_entry(codec, &bus->codec_list, list) {
4955 if (hda_codec_is_power_on(codec) &&
4956 codec->patch_ops.reboot_notify)
4957 codec->patch_ops.reboot_notify(codec);
4958 }
4959}
4960EXPORT_SYMBOL_GPL(snd_hda_bus_reboot_notify);
4961
4962/**
4963 * snd_hda_multi_out_dig_open - open the digital out in the exclusive mode 4945 * snd_hda_multi_out_dig_open - open the digital out in the exclusive mode
4964 * @codec: the HDA codec 4946 * @codec: the HDA codec
4965 * @mout: hda_multi_out object 4947 * @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[];
563 * Misc 563 * Misc
564 */ 564 */
565void snd_hda_get_codec_name(struct hda_codec *codec, char *name, int namelen); 565void snd_hda_get_codec_name(struct hda_codec *codec, char *name, int namelen);
566void snd_hda_bus_reboot_notify(struct hda_bus *bus);
567void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg, 566void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg,
568 unsigned int power_state); 567 unsigned int power_state);
569 568
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 @@
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/pm_runtime.h> 28#include <linux/pm_runtime.h>
29#include <linux/slab.h> 29#include <linux/slab.h>
30#include <linux/reboot.h>
31#include <sound/core.h> 30#include <sound/core.h>
32#include <sound/initval.h> 31#include <sound/initval.h>
33#include "hda_controller.h" 32#include "hda_controller.h"
@@ -1972,30 +1971,5 @@ int azx_init_stream(struct azx *chip)
1972} 1971}
1973EXPORT_SYMBOL_GPL(azx_init_stream); 1972EXPORT_SYMBOL_GPL(azx_init_stream);
1974 1973
1975/*
1976 * reboot notifier for hang-up problem at power-down
1977 */
1978static int azx_halt(struct notifier_block *nb, unsigned long event, void *buf)
1979{
1980 struct azx *chip = container_of(nb, struct azx, reboot_notifier);
1981 snd_hda_bus_reboot_notify(chip->bus);
1982 azx_stop_chip(chip);
1983 return NOTIFY_OK;
1984}
1985
1986void azx_notifier_register(struct azx *chip)
1987{
1988 chip->reboot_notifier.notifier_call = azx_halt;
1989 register_reboot_notifier(&chip->reboot_notifier);
1990}
1991EXPORT_SYMBOL_GPL(azx_notifier_register);
1992
1993void azx_notifier_unregister(struct azx *chip)
1994{
1995 if (chip->reboot_notifier.notifier_call)
1996 unregister_reboot_notifier(&chip->reboot_notifier);
1997}
1998EXPORT_SYMBOL_GPL(azx_notifier_unregister);
1999
2000MODULE_LICENSE("GPL"); 1974MODULE_LICENSE("GPL");
2001MODULE_DESCRIPTION("Common HDA driver functions"); 1975MODULE_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 {
362 /* for debugging */ 362 /* for debugging */
363 unsigned int last_cmd[AZX_MAX_CODECS]; 363 unsigned int last_cmd[AZX_MAX_CODECS];
364 364
365 /* reboot notifier (for mysterious hangup problem at power-down) */
366 struct notifier_block reboot_notifier;
367
368#ifdef CONFIG_SND_HDA_DSP_LOADER 365#ifdef CONFIG_SND_HDA_DSP_LOADER
369 struct azx_dev saved_azx_dev; 366 struct azx_dev saved_azx_dev;
370#endif 367#endif
@@ -437,7 +434,4 @@ int azx_probe_codecs(struct azx *chip, unsigned int max_slots);
437int azx_codec_configure(struct azx *chip); 434int azx_codec_configure(struct azx *chip);
438int azx_init_stream(struct azx *chip); 435int azx_init_stream(struct azx *chip);
439 436
440void azx_notifier_register(struct azx *chip);
441void azx_notifier_unregister(struct azx *chip);
442
443#endif /* __SOUND_HDA_CONTROLLER_H */ 437#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)
1066 1066
1067 azx_del_card_list(chip); 1067 azx_del_card_list(chip);
1068 1068
1069 azx_notifier_unregister(chip);
1070
1071 hda->init_failed = 1; /* to be sure */ 1069 hda->init_failed = 1; /* to be sure */
1072 complete_all(&hda->probe_wait); 1070 complete_all(&hda->probe_wait);
1073 1071
@@ -1900,7 +1898,6 @@ static int azx_probe_continue(struct azx *chip)
1900 goto out_free; 1898 goto out_free;
1901 1899
1902 chip->running = 1; 1900 chip->running = 1;
1903 azx_notifier_register(chip);
1904 azx_add_card_list(chip); 1901 azx_add_card_list(chip);
1905 snd_hda_set_power_save(chip->bus, power_save * 1000); 1902 snd_hda_set_power_save(chip->bus, power_save * 1000);
1906 if (azx_has_pm_runtime(chip) || hda->use_vga_switcheroo) 1903 if (azx_has_pm_runtime(chip) || hda->use_vga_switcheroo)
@@ -1921,6 +1918,18 @@ static void azx_remove(struct pci_dev *pci)
1921 snd_card_free(card); 1918 snd_card_free(card);
1922} 1919}
1923 1920
1921static void azx_shutdown(struct pci_dev *pci)
1922{
1923 struct snd_card *card = pci_get_drvdata(pci);
1924 struct azx *chip;
1925
1926 if (!card)
1927 return;
1928 chip = card->private_data;
1929 if (chip && chip->running)
1930 azx_stop_chip(chip);
1931}
1932
1924/* PCI IDs */ 1933/* PCI IDs */
1925static const struct pci_device_id azx_ids[] = { 1934static const struct pci_device_id azx_ids[] = {
1926 /* CPT */ 1935 /* CPT */
@@ -2143,6 +2152,7 @@ static struct pci_driver azx_driver = {
2143 .id_table = azx_ids, 2152 .id_table = azx_ids,
2144 .probe = azx_probe, 2153 .probe = azx_probe,
2145 .remove = azx_remove, 2154 .remove = azx_remove,
2155 .shutdown = azx_shutdown,
2146 .driver = { 2156 .driver = {
2147 .pm = AZX_PM_OPS, 2157 .pm = AZX_PM_OPS,
2148 }, 2158 },
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)
290 int i; 290 int i;
291 struct azx *chip = device->device_data; 291 struct azx *chip = device->device_data;
292 292
293 azx_notifier_unregister(chip);
294
295 if (chip->initialized) { 293 if (chip->initialized) {
296 for (i = 0; i < chip->num_streams; i++) 294 for (i = 0; i < chip->num_streams; i++)
297 azx_stream_stop(chip, &chip->azx_dev[i]); 295 azx_stream_stop(chip, &chip->azx_dev[i]);
@@ -502,7 +500,6 @@ static int hda_tegra_probe(struct platform_device *pdev)
502 goto out_free; 500 goto out_free;
503 501
504 chip->running = 1; 502 chip->running = 1;
505 azx_notifier_register(chip);
506 snd_hda_set_power_save(chip->bus, power_save * 1000); 503 snd_hda_set_power_save(chip->bus, power_save * 1000);
507 504
508 return 0; 505 return 0;
@@ -517,6 +514,18 @@ static int hda_tegra_remove(struct platform_device *pdev)
517 return snd_card_free(dev_get_drvdata(&pdev->dev)); 514 return snd_card_free(dev_get_drvdata(&pdev->dev));
518} 515}
519 516
517static void hda_tegra_shutdown(struct platform_device *pdev)
518{
519 struct snd_card *card = dev_get_drvdata(&pdev->dev);
520 struct azx *chip;
521
522 if (!card)
523 return;
524 chip = card->private_data;
525 if (chip && chip->running)
526 azx_stop_chip(chip);
527}
528
520static struct platform_driver tegra_platform_hda = { 529static struct platform_driver tegra_platform_hda = {
521 .driver = { 530 .driver = {
522 .name = "tegra-hda", 531 .name = "tegra-hda",
@@ -525,6 +534,7 @@ static struct platform_driver tegra_platform_hda = {
525 }, 534 },
526 .probe = hda_tegra_probe, 535 .probe = hda_tegra_probe,
527 .remove = hda_tegra_remove, 536 .remove = hda_tegra_remove,
537 .shutdown = hda_tegra_shutdown,
528}; 538};
529module_platform_driver(tegra_platform_hda); 539module_platform_driver(tegra_platform_hda);
530 540