Commit 65fcd41d authored by Takashi Iwai's avatar Takashi Iwai

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: default avatarTakashi Iwai <tiwai@suse.de>
parent c376e2c7
...@@ -110,8 +110,15 @@ MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode " ...@@ -110,8 +110,15 @@ MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode "
#endif #endif
#ifdef CONFIG_SND_HDA_POWER_SAVE #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; 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 " MODULE_PARM_DESC(power_save, "Automatic power-saving timeout "
"(in second, 0 = disable)."); "(in second, 0 = disable).");
...@@ -502,6 +509,9 @@ struct azx { ...@@ -502,6 +509,9 @@ struct azx {
/* reboot notifier (for mysterious hangup problem at power-down) */ /* reboot notifier (for mysterious hangup problem at power-down) */
struct notifier_block reboot_notifier; struct notifier_block reboot_notifier;
/* card list (for power_save trigger) */
struct list_head list;
}; };
/* driver types */ /* driver types */
...@@ -2407,6 +2417,48 @@ static void azx_power_notify(struct hda_bus *bus) ...@@ -2407,6 +2417,48 @@ static void azx_power_notify(struct hda_bus *bus)
!bus->power_keep_link_on) !bus->power_keep_link_on)
azx_stop_chip(chip); 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 */ #endif /* CONFIG_SND_HDA_POWER_SAVE */
#if defined(CONFIG_PM_SLEEP) || defined(SUPPORT_VGA_SWITCHEROO) #if defined(CONFIG_PM_SLEEP) || defined(SUPPORT_VGA_SWITCHEROO)
...@@ -2604,6 +2656,8 @@ static int azx_free(struct azx *chip) ...@@ -2604,6 +2656,8 @@ static int azx_free(struct azx *chip)
{ {
int i; int i;
azx_del_card_list(chip);
azx_notifier_unregister(chip); azx_notifier_unregister(chip);
if (use_vga_switcheroo(chip)) { if (use_vga_switcheroo(chip)) {
...@@ -2911,6 +2965,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, ...@@ -2911,6 +2965,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
chip->dev_index = dev; chip->dev_index = dev;
INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work); INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work);
INIT_LIST_HEAD(&chip->pcm_list); INIT_LIST_HEAD(&chip->pcm_list);
INIT_LIST_HEAD(&chip->list);
init_vga_switcheroo(chip); init_vga_switcheroo(chip);
chip->position_fix[0] = chip->position_fix[1] = chip->position_fix[0] = chip->position_fix[1] =
...@@ -3288,6 +3343,7 @@ static int DELAYED_INIT_MARK azx_probe_continue(struct azx *chip) ...@@ -3288,6 +3343,7 @@ static int DELAYED_INIT_MARK azx_probe_continue(struct azx *chip)
chip->running = 1; chip->running = 1;
power_down_all_codecs(chip); power_down_all_codecs(chip);
azx_notifier_register(chip); azx_notifier_register(chip);
azx_add_card_list(chip);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment