ALSA: hda - Fix possible runtime PM refcount unbalance

When the driver is unloaded before the codec is bound, it still keeps
the runtime PM refcount up, and results in the unbalance.  This patch
covers these cases by introducing a flag indicating the runtime PM
initialization and handling the codec registration procedure more
properly.  It also fixes the missing input beep device as a gratis,
too.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 36483f7..145cae7 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -912,6 +912,13 @@
 
 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 @@
 static unsigned int hda_set_power_state(struct hda_codec *codec,
 				unsigned int power_state);
 
+/* also called from hda_bind.c */
+void snd_hda_codec_register(struct hda_codec *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);
+		codec->registered = 1;
+	}
+}
+
 static int snd_hda_codec_dev_register(struct snd_device *device)
 {
-	struct hda_codec *codec = device->device_data;
-
-	snd_hda_register_beep_device(codec);
-	if (device_is_registered(hda_codec_dev(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);
+	snd_hda_codec_register(device->device_data);
 	return 0;
 }
 
@@ -1094,7 +1109,6 @@
 	return 0;
 
  error:
-	pm_runtime_put_noidle(hda_codec_dev(codec));
 	put_device(hda_codec_dev(codec));
 	return err;
 }