diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/hda/hda_intel.c | 47 |
1 files changed, 45 insertions, 2 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 7b7fc90b1f0c..cc32d89e8b03 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -441,6 +441,7 @@ struct azx { /* platform driver clocks */ struct clk **platform_clks; int platform_clk_count; + int platform_clk_enable; #endif /* locks */ @@ -1276,14 +1277,21 @@ static void azx_platform_enable_clocks(struct azx *chip) for (i = 0; i < chip->platform_clk_count; i++) clk_enable(chip->platform_clks[i]); + + chip->platform_clk_enable++; } static void azx_platform_disable_clocks(struct azx *chip) { int i; + if (!chip->platform_clk_enable) + return; + for (i = 0; i < chip->platform_clk_count; i++) clk_disable(chip->platform_clks[i]); + + chip->platform_clk_enable--; } #endif /* CONFIG_SND_HDA_PLATFORM_DRIVER */ @@ -2374,11 +2382,19 @@ static void azx_power_notify(struct hda_bus *bus) break; } } - if (power_on) + if (power_on) { +#ifdef CONFIG_SND_HDA_PLATFORM_DRIVER + azx_platform_enable_clocks(chip); +#endif azx_init_chip(chip, 1); + } else if (chip->running && power_save_controller && - !bus->power_keep_link_on) + !bus->power_keep_link_on) { azx_stop_chip(chip); +#ifdef CONFIG_SND_HDA_PLATFORM_DRIVER + azx_platform_disable_clocks(chip); +#endif + } } #endif /* CONFIG_SND_HDA_POWER_SAVE */ @@ -2403,6 +2419,12 @@ static int azx_suspend(struct azx *chip, pm_message_t state) struct snd_card *card = chip->card; int i; +#if defined(CONFIG_SND_HDA_PLATFORM_DRIVER) && \ + defined(CONFIG_SND_HDA_POWER_SAVE) + if (!chip->platform_clk_enable) + azx_platform_enable_clocks(chip); +#endif + snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); azx_clear_irq_pending(chip); for (i = 0; i < HDA_MAX_PCMS; i++) @@ -2472,6 +2494,13 @@ static int azx_resume(struct azx *chip) snd_hda_resume(chip->bus); snd_power_change_state(card, SNDRV_CTL_POWER_D0); + +#if defined(CONFIG_SND_HDA_PLATFORM_DRIVER) && \ + defined(CONFIG_SND_HDA_POWER_SAVE) + if (chip->pdev) + azx_platform_disable_clocks(chip); +#endif + return 0; } @@ -2518,8 +2547,22 @@ static int azx_resume_platform(struct platform_device *pdev) static int azx_halt(struct notifier_block *nb, unsigned long event, void *buf) { struct azx *chip = container_of(nb, struct azx, reboot_notifier); + +#if defined(CONFIG_SND_HDA_PLATFORM_DRIVER) && \ + defined(CONFIG_SND_HDA_POWER_SAVE) + if (chip->pdev) + azx_platform_enable_clocks(chip); +#endif + snd_hda_bus_reboot_notify(chip->bus); azx_stop_chip(chip); + +#if defined(CONFIG_SND_HDA_PLATFORM_DRIVER) && \ + defined(CONFIG_SND_HDA_POWER_SAVE) + if (chip->pdev) + azx_platform_disable_clocks(chip); +#endif + return NOTIFY_OK; } |