Many thanks, Takashi! These two patches work well.
Mengdong
-----Original Message----- From: Takashi Iwai [mailto:tiwai@suse.de] Sent: Tuesday, August 14, 2012 11:21 PM To: Lin, Mengdong Cc: alsa-devel@alsa-project.org Subject: [PATCH 2/2] ALSA: hda - Check the power state when power_save option is changed
... by calling the newly introduced snd_hda_power_sync().
I had to reimplement a wheel for adding the trigger at changing the parameter -- the parameter set ops is overwritten to pass the integer parameter, then trigger the power-state sync.
Signed-off-by: Takashi Iwai tiwai@suse.de
sound/pci/hda/hda_intel.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-)
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 23ad7e2..330a5ff 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -110,8 +110,15 @@ MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode " #endif
#ifdef CONFIG_SND_HDA_POWER_SAVE +static int param_set_xint(const char *val, const struct kernel_param +*kp); static struct kernel_param_ops param_ops_xint = {
- .set = param_set_xint,
- .get = param_get_int,
+}; +#define param_check_xint param_check_int
static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT; -module_param(power_save, int, 0644); +module_param(power_save, xint, 0644); MODULE_PARM_DESC(power_save, "Automatic power-saving timeout " "(in second, 0 = disable).");
@@ -502,6 +509,9 @@ struct azx {
/* reboot notifier (for mysterious hangup problem at power-down) */ struct notifier_block reboot_notifier;
- /* card list (for power_save trigger) */
- struct list_head list;
};
/* driver types */ @@ -2407,6 +2417,48 @@ static void azx_power_notify(struct hda_bus *bus) !bus->power_keep_link_on) azx_stop_chip(chip); }
+static DEFINE_MUTEX(card_list_lock); +static LIST_HEAD(card_list);
+static void azx_add_card_list(struct azx *chip) {
- mutex_lock(&card_list_lock);
- list_add(&chip->list, &card_list);
- mutex_unlock(&card_list_lock);
+}
+static void azx_del_card_list(struct azx *chip) {
- mutex_lock(&card_list_lock);
- list_del_init(&chip->list);
- mutex_unlock(&card_list_lock);
+}
+/* trigger power-save check at writing parameter */ static int +param_set_xint(const char *val, const struct kernel_param *kp) {
- struct azx *chip;
- struct hda_codec *c;
- int prev = power_save;
- int ret = param_set_int(val, kp);
- if (ret || prev == power_save)
return ret;
- mutex_lock(&card_list_lock);
- list_for_each_entry(chip, &card_list, list) {
if (!chip->bus || chip->disabled)
continue;
list_for_each_entry(c, &chip->bus->codec_list, list)
snd_hda_power_sync(c);
- }
- mutex_unlock(&card_list_lock);
- return 0;
+} +#else +#define azx_add_card_list(chip) /* NOP */ #define +azx_del_card_list(chip) /* NOP */ #endif /* CONFIG_SND_HDA_POWER_SAVE */
#ifdef CONFIG_PM @@ -2607,6 +2659,8 @@ static int azx_free(struct azx *chip) { int i;
azx_del_card_list(chip);
azx_notifier_unregister(chip);
if (use_vga_switcheroo(chip)) {
@@ -2914,6 +2968,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, chip->dev_index = dev; INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work); INIT_LIST_HEAD(&chip->pcm_list);
INIT_LIST_HEAD(&chip->list); init_vga_switcheroo(chip);
chip->position_fix[0] = chip->position_fix[1] = @@ -3291,6 +3346,7
@@ static int DELAYED_INIT_MARK azx_probe_continue(struct azx *chip) chip->running = 1; power_down_all_codecs(chip); azx_notifier_register(chip);
azx_add_card_list(chip);
return 0;
-- 1.7.11.4