summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2015-03-05 17:21:32 +0100
committerTakashi Iwai <tiwai@suse.de>2015-03-13 15:28:58 +0100
commitb2a0bafa758256442e04d1f34d6d0746b846d23d (patch)
tree97f3ada5d1e4aced0254f856bf819bc9dca57b89
parentd56db741b8e688a0b9d4d5bb9caa11dfcb7c0b08 (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.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 @@
#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);