diff options
-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 @@ | |||
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 | ||
146 | static 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 | |||
145 | int __hda_codec_driver_register(struct hda_codec_driver *drv, const char *name, | 154 | int __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 | */ | ||
4948 | void 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 | } | ||
4960 | EXPORT_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 | */ |
565 | void snd_hda_get_codec_name(struct hda_codec *codec, char *name, int namelen); | 565 | void snd_hda_get_codec_name(struct hda_codec *codec, char *name, int namelen); |
566 | void snd_hda_bus_reboot_notify(struct hda_bus *bus); | ||
567 | void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg, | 566 | void 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 | } |
1973 | EXPORT_SYMBOL_GPL(azx_init_stream); | 1972 | EXPORT_SYMBOL_GPL(azx_init_stream); |
1974 | 1973 | ||
1975 | /* | ||
1976 | * reboot notifier for hang-up problem at power-down | ||
1977 | */ | ||
1978 | static 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 | |||
1986 | void azx_notifier_register(struct azx *chip) | ||
1987 | { | ||
1988 | chip->reboot_notifier.notifier_call = azx_halt; | ||
1989 | register_reboot_notifier(&chip->reboot_notifier); | ||
1990 | } | ||
1991 | EXPORT_SYMBOL_GPL(azx_notifier_register); | ||
1992 | |||
1993 | void azx_notifier_unregister(struct azx *chip) | ||
1994 | { | ||
1995 | if (chip->reboot_notifier.notifier_call) | ||
1996 | unregister_reboot_notifier(&chip->reboot_notifier); | ||
1997 | } | ||
1998 | EXPORT_SYMBOL_GPL(azx_notifier_unregister); | ||
1999 | |||
2000 | MODULE_LICENSE("GPL"); | 1974 | MODULE_LICENSE("GPL"); |
2001 | MODULE_DESCRIPTION("Common HDA driver functions"); | 1975 | 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 { | |||
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); | |||
437 | int azx_codec_configure(struct azx *chip); | 434 | int azx_codec_configure(struct azx *chip); |
438 | int azx_init_stream(struct azx *chip); | 435 | int azx_init_stream(struct azx *chip); |
439 | 436 | ||
440 | void azx_notifier_register(struct azx *chip); | ||
441 | void 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 | ||
1921 | static 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 */ |
1925 | static const struct pci_device_id azx_ids[] = { | 1934 | static 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 | ||
517 | static 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 | |||
520 | static struct platform_driver tegra_platform_hda = { | 529 | static 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 | }; |
529 | module_platform_driver(tegra_platform_hda); | 539 | module_platform_driver(tegra_platform_hda); |
530 | 540 | ||