summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/hda/hdac_device.c3
-rw-r--r--sound/pci/hda/hda_bind.c1
-rw-r--r--sound/pci/hda/hda_codec.c30
-rw-r--r--sound/pci/hda/hda_codec.h1
-rw-r--r--sound/pci/hda/hda_local.h1
5 files changed, 26 insertions, 10 deletions
diff --git a/sound/hda/hdac_device.c b/sound/hda/hdac_device.c
index aaece36247e7..6e8ee1d6974a 100644
--- a/sound/hda/hdac_device.c
+++ b/sound/hda/hdac_device.c
@@ -109,7 +109,6 @@ int snd_hdac_device_init(struct hdac_device *codec, struct hdac_bus *bus,
return 0;
error:
- pm_runtime_put_noidle(&codec->dev);
put_device(&codec->dev);
return err;
}
@@ -121,7 +120,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_device_init);
*/
void snd_hdac_device_exit(struct hdac_device *codec)
{
- /* pm_runtime_put_noidle(&codec->dev); */
+ pm_runtime_put_noidle(&codec->dev);
snd_hdac_bus_remove_device(codec->bus, codec);
kfree(codec->vendor_name);
kfree(codec->chip_name);
diff --git a/sound/pci/hda/hda_bind.c b/sound/pci/hda/hda_bind.c
index 130f672e6f37..7b269c3237e3 100644
--- a/sound/pci/hda/hda_bind.c
+++ b/sound/pci/hda/hda_bind.c
@@ -95,6 +95,7 @@ static int hda_codec_driver_probe(struct device *dev)
err = snd_card_register(codec->card);
if (err < 0)
goto error_module;
+ snd_hda_codec_register(codec);
}
return 0;
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 36483f7dd3ce..145cae7903b6 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -912,6 +912,13 @@ static void codec_release_pcms(struct hda_codec *codec)
void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec)
{
+ if (codec->registered) {
+ /* pm_runtime_put() is called in snd_hdac_device_exit() */
+ pm_runtime_get_noresume(hda_codec_dev(codec));
+ pm_runtime_disable(hda_codec_dev(codec));
+ codec->registered = 0;
+ }
+
cancel_delayed_work_sync(&codec->jackpoll_work);
if (!codec->in_freeing)
snd_hda_ctls_clear(codec);
@@ -943,15 +950,23 @@ void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec)
static unsigned int hda_set_power_state(struct hda_codec *codec,
unsigned int power_state);
-static int snd_hda_codec_dev_register(struct snd_device *device)
+/* also called from hda_bind.c */
+void snd_hda_codec_register(struct hda_codec *codec)
{
- struct hda_codec *codec = device->device_data;
-
- snd_hda_register_beep_device(codec);
- if (device_is_registered(hda_codec_dev(codec)))
+ if (codec->registered)
+ return;
+ if (device_is_registered(hda_codec_dev(codec))) {
+ snd_hda_register_beep_device(codec);
pm_runtime_enable(hda_codec_dev(codec));
- /* it was powered up in snd_hda_codec_new(), now all done */
- snd_hda_power_down(codec);
+ /* it was powered up in snd_hda_codec_new(), now all done */
+ snd_hda_power_down(codec);
+ codec->registered = 1;
+ }
+}
+
+static int snd_hda_codec_dev_register(struct snd_device *device)
+{
+ snd_hda_codec_register(device->device_data);
return 0;
}
@@ -1094,7 +1109,6 @@ int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card,
return 0;
error:
- pm_runtime_put_noidle(hda_codec_dev(codec));
put_device(hda_codec_dev(codec));
return err;
}
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index e7c47a439762..76776164623d 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -314,6 +314,7 @@ struct hda_codec {
/* misc flags */
unsigned int in_freeing:1; /* being released */
+ unsigned int registered:1; /* codec was registered */
unsigned int spdif_status_reset :1; /* needs to toggle SPDIF for each
* status change
* (e.g. Realtek codecs)
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index e0db30c66e5f..8a83775e0e27 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -150,6 +150,7 @@ int __snd_hda_add_vmaster(struct hda_codec *codec, char *name,
#define snd_hda_add_vmaster(codec, name, tlv, slaves, suffix) \
__snd_hda_add_vmaster(codec, name, tlv, slaves, suffix, true, NULL)
int snd_hda_codec_reset(struct hda_codec *codec);
+void snd_hda_codec_register(struct hda_codec *codec);
void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec);
enum {