[ALSA] ac97 - Suppress power-saving mode on non-supporting drivers

Don't enable power-saving mode on drivers that don't support
it.  The supporting drivers set AC97_SCAP_POWER_SAVE to scaps
at creation of ac97 instance.
Currently enable on the following drivers: intel8x0, intel8x0m,
atiixp, atiixp-modem, via82xx and via82xx-modem.
Also, a bit clean up of power-saving stuff:
- Don't create an own workq
- Remove superfluous ifdefs

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
index 5f7c78d..5d3f0d8 100644
--- a/include/sound/ac97_codec.h
+++ b/include/sound/ac97_codec.h
@@ -375,6 +375,7 @@
 #define AC97_SCAP_DETECT_BY_VENDOR (1<<8) /* use vendor registers for read tests */
 #define AC97_SCAP_NO_SPDIF	(1<<9)	/* don't build SPDIF controls */
 #define AC97_SCAP_EAPD_LED	(1<<10)	/* EAPD as mute LED */
+#define AC97_SCAP_POWER_SAVE	(1<<11)	/* capable for aggresive power-saving */
 
 /* ac97->flags */
 #define AC97_HAS_PC_BEEP	(1<<0)	/* force PC Speaker usage */
@@ -511,7 +512,6 @@
 
 #ifdef CONFIG_SND_AC97_POWER_SAVE
 	unsigned int power_up;	/* power states */
-	struct workqueue_struct *power_workq;
 	struct delayed_work power_work;
 #endif
 	struct device dev;
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index d2994cb..9da4977 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -194,6 +194,13 @@
 
 
 static void update_power_regs(struct snd_ac97 *ac97);
+#ifdef CONFIG_SND_AC97_POWER_SAVE
+#define ac97_is_power_save_mode(ac97) \
+	((ac97->scaps & AC97_SCAP_POWER_SAVE) && power_save)
+#else
+#define ac97_is_power_save_mode(ac97) 0
+#endif
+
 
 /*
  *  I/O routines
@@ -982,8 +989,7 @@
 {
 	if (ac97) {
 #ifdef CONFIG_SND_AC97_POWER_SAVE
-		if (ac97->power_workq)
-			destroy_workqueue(ac97->power_workq);
+		cancel_delayed_work(&ac97->power_work);
 #endif
 		snd_ac97_proc_done(ac97);
 		if (ac97->bus)
@@ -1989,7 +1995,6 @@
 	mutex_init(&ac97->reg_mutex);
 	mutex_init(&ac97->page_mutex);
 #ifdef CONFIG_SND_AC97_POWER_SAVE
-	ac97->power_workq = create_workqueue("ac97");
 	INIT_DELAYED_WORK(&ac97->power_work, do_update_power);
 #endif
 
@@ -2275,15 +2280,13 @@
 	udelay(100);
 	power |= AC97_PD_PR2 | AC97_PD_PR3;	/* Analog Mixer powerdown */
 	snd_ac97_write(ac97, AC97_POWERDOWN, power);
-#ifdef CONFIG_SND_AC97_POWER_SAVE
-	if (power_save) {
+	if (ac97_is_power_save_mode(ac97)) {
 		udelay(100);
 		/* AC-link powerdown, internal Clk disable */
 		/* FIXME: this may cause click noises on some boards */
 		power |= AC97_PD_PR4 | AC97_PD_PR5;
 		snd_ac97_write(ac97, AC97_POWERDOWN, power);
 	}
-#endif
 }
 
 
@@ -2337,14 +2340,16 @@
 		}
 	}
 
-	if (power_save && !powerup && ac97->power_workq)
+	if (ac97_is_power_save_mode(ac97) && !powerup)
 		/* adjust power-down bits after two seconds delay
 		 * (for avoiding loud click noises for many (OSS) apps
 		 *  that open/close frequently)
 		 */
-		queue_delayed_work(ac97->power_workq, &ac97->power_work, HZ*2);
-	else
+		schedule_delayed_work(&ac97->power_work, HZ*2);
+	else {
+		cancel_delayed_work(&ac97->power_work);
 		update_power_regs(ac97);
+	}
 
 	return 0;
 }
@@ -2357,19 +2362,15 @@
 	unsigned int power_up, bits;
 	int i;
 
+	power_up = (1 << PWIDX_FRONT) | (1 << PWIDX_ADC);
+	power_up |= (1 << PWIDX_MIC);
+	if (ac97->scaps & AC97_SCAP_SURROUND_DAC)
+		power_up |= (1 << PWIDX_SURR);
+	if (ac97->scaps & AC97_SCAP_CENTER_LFE_DAC)
+		power_up |= (1 << PWIDX_CLFE);
 #ifdef CONFIG_SND_AC97_POWER_SAVE
-	if (power_save)
+	if (ac97_is_power_save_mode(ac97))
 		power_up = ac97->power_up;
-	else {
-#endif
-		power_up = (1 << PWIDX_FRONT) | (1 << PWIDX_ADC);
-		power_up |= (1 << PWIDX_MIC);
-		if (ac97->scaps & AC97_SCAP_SURROUND_DAC)
-			power_up |= (1 << PWIDX_SURR);
-		if (ac97->scaps & AC97_SCAP_CENTER_LFE_DAC)
-			power_up |= (1 << PWIDX_CLFE);
-#ifdef CONFIG_SND_AC97_POWER_SAVE
-	}
 #endif
 	if (power_up) {
 		if (ac97->regs[AC97_POWERDOWN] & AC97_PD_PR2) {
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 476c343..86710df 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -1396,7 +1396,7 @@
 		ac97.private_data = chip;
 		ac97.pci = chip->pci;
 		ac97.num = i;
-		ac97.scaps = AC97_SCAP_SKIP_MODEM;
+		ac97.scaps = AC97_SCAP_SKIP_MODEM | AC97_SCAP_POWER_SAVE;
 		if (! chip->spdif_over_aclink)
 			ac97.scaps |= AC97_SCAP_NO_SPDIF;
 		if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i])) < 0) {
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index cc2e6b9..904023f 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -1090,7 +1090,7 @@
 		ac97.private_data = chip;
 		ac97.pci = chip->pci;
 		ac97.num = i;
-		ac97.scaps = AC97_SCAP_SKIP_AUDIO;
+		ac97.scaps = AC97_SCAP_SKIP_AUDIO | AC97_SCAP_POWER_SAVE;
 		if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i])) < 0) {
 			chip->ac97[i] = NULL; /* to be sure */
 			snd_printdd("atiixp-modem: codec %d not available for modem\n", i);
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 28d5d9d..f8aef13 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -2057,7 +2057,7 @@
 	memset(&ac97, 0, sizeof(ac97));
 	ac97.private_data = chip;
 	ac97.private_free = snd_intel8x0_mixer_free_ac97;
-	ac97.scaps = AC97_SCAP_SKIP_MODEM;
+	ac97.scaps = AC97_SCAP_SKIP_MODEM | AC97_SCAP_POWER_SAVE;
 	if (chip->xbox)
 		ac97.scaps |= AC97_SCAP_DETECT_BY_VENDOR;
 	if (chip->device_type != DEVICE_ALI) {
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index 936c3cf..c155e1f 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -830,7 +830,7 @@
 	memset(&ac97, 0, sizeof(ac97));
 	ac97.private_data = chip;
 	ac97.private_free = snd_intel8x0_mixer_free_ac97;
-	ac97.scaps = AC97_SCAP_SKIP_AUDIO;
+	ac97.scaps = AC97_SCAP_SKIP_AUDIO | AC97_SCAP_POWER_SAVE;
 
 	glob_sta = igetdword(chip, ICHREG(GLOB_STA));
 
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index a572b01..0440df7 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -1823,7 +1823,7 @@
 	ac97.private_data = chip;
 	ac97.private_free = snd_via82xx_mixer_free_ac97;
 	ac97.pci = chip->pci;
-	ac97.scaps = AC97_SCAP_SKIP_MODEM;
+	ac97.scaps = AC97_SCAP_SKIP_MODEM | AC97_SCAP_POWER_SAVE;
 	if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0)
 		return err;
 
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index 17d6b84..b338e15 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -900,7 +900,7 @@
 	ac97.private_data = chip;
 	ac97.private_free = snd_via82xx_mixer_free_ac97;
 	ac97.pci = chip->pci;
-	ac97.scaps = AC97_SCAP_SKIP_AUDIO;
+	ac97.scaps = AC97_SCAP_SKIP_AUDIO | AC97_SCAP_POWER_SAVE;
 	ac97.num = chip->ac97_secondary;
 
 	if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0)