Commit 3baffc4a authored by Takashi Iwai's avatar Takashi Iwai

ALSA: hda/intel: Refactoring PM code

Make unified suspend / resume helpers and call them from both the
runtime- and the system-PM callbacks for simplifying code.

There are slight changes of call orders, but there shouldn't be any
functional difference after refactoring.
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent fa9c98e4
...@@ -930,35 +930,82 @@ static int param_set_xint(const char *val, const struct kernel_param *kp) ...@@ -930,35 +930,82 @@ static int param_set_xint(const char *val, const struct kernel_param *kp)
mutex_unlock(&card_list_lock); mutex_unlock(&card_list_lock);
return 0; return 0;
} }
#else
#define azx_add_card_list(chip) /* NOP */
#define azx_del_card_list(chip) /* NOP */
#endif /* CONFIG_PM */
#ifdef CONFIG_PM_SLEEP
/* /*
* power management * power management
*/ */
static int azx_suspend(struct device *dev) static bool azx_is_pm_ready(struct snd_card *card)
{ {
struct snd_card *card = dev_get_drvdata(dev);
struct azx *chip; struct azx *chip;
struct hda_intel *hda; struct hda_intel *hda;
struct hdac_bus *bus;
if (!card) if (!card)
return 0; return false;
chip = card->private_data; chip = card->private_data;
hda = container_of(chip, struct hda_intel, chip); hda = container_of(chip, struct hda_intel, chip);
if (chip->disabled || hda->init_failed || !chip->running) if (chip->disabled || hda->init_failed || !chip->running)
return false;
return true;
}
static void __azx_runtime_suspend(struct azx *chip)
{
struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
azx_stop_chip(chip);
azx_enter_link_reset(chip);
azx_clear_irq_pending(chip);
if ((chip->driver_caps & AZX_DCAPS_I915_POWERWELL) &&
hda->need_i915_power)
snd_hdac_display_power(azx_bus(chip), false);
}
static void __azx_runtime_resume(struct azx *chip)
{
struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
struct hdac_bus *bus = azx_bus(chip);
struct hda_codec *codec;
int status;
if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
snd_hdac_display_power(bus, true);
if (hda->need_i915_power)
snd_hdac_i915_set_bclk(bus);
}
/* Read STATESTS before controller reset */
status = azx_readw(chip, STATESTS);
azx_init_pci(chip);
hda_intel_init_chip(chip, true);
if (status) {
list_for_each_codec(codec, &chip->bus)
if (status & (1 << codec->addr))
schedule_delayed_work(&codec->jackpoll_work,
codec->jackpoll_interval);
}
/* power down again for link-controlled chips */
if ((chip->driver_caps & AZX_DCAPS_I915_POWERWELL) &&
!hda->need_i915_power)
snd_hdac_display_power(bus, false);
}
#ifdef CONFIG_PM_SLEEP
static int azx_suspend(struct device *dev)
{
struct snd_card *card = dev_get_drvdata(dev);
struct azx *chip;
struct hdac_bus *bus;
if (!azx_is_pm_ready(card))
return 0; return 0;
chip = card->private_data;
bus = azx_bus(chip); bus = azx_bus(chip);
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
azx_clear_irq_pending(chip); __azx_runtime_suspend(chip);
azx_stop_chip(chip);
azx_enter_link_reset(chip);
if (bus->irq >= 0) { if (bus->irq >= 0) {
free_irq(bus->irq, chip); free_irq(bus->irq, chip);
bus->irq = -1; bus->irq = -1;
...@@ -966,9 +1013,6 @@ static int azx_suspend(struct device *dev) ...@@ -966,9 +1013,6 @@ static int azx_suspend(struct device *dev)
if (chip->msi) if (chip->msi)
pci_disable_msi(chip->pci); pci_disable_msi(chip->pci);
if ((chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
&& hda->need_i915_power)
snd_hdac_display_power(bus, false);
trace_azx_suspend(chip); trace_azx_suspend(chip);
return 0; return 0;
...@@ -976,41 +1020,19 @@ static int azx_suspend(struct device *dev) ...@@ -976,41 +1020,19 @@ static int azx_suspend(struct device *dev)
static int azx_resume(struct device *dev) static int azx_resume(struct device *dev)
{ {
struct pci_dev *pci = to_pci_dev(dev);
struct snd_card *card = dev_get_drvdata(dev); struct snd_card *card = dev_get_drvdata(dev);
struct azx *chip; struct azx *chip;
struct hda_intel *hda;
struct hdac_bus *bus;
if (!card) if (!azx_is_pm_ready(card))
return 0; return 0;
chip = card->private_data; chip = card->private_data;
hda = container_of(chip, struct hda_intel, chip);
bus = azx_bus(chip);
if (chip->disabled || hda->init_failed || !chip->running)
return 0;
if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
snd_hdac_display_power(bus, true);
if (hda->need_i915_power)
snd_hdac_i915_set_bclk(bus);
}
if (chip->msi) if (chip->msi)
if (pci_enable_msi(pci) < 0) if (pci_enable_msi(chip->pci) < 0)
chip->msi = 0; chip->msi = 0;
if (azx_acquire_irq(chip, 1) < 0) if (azx_acquire_irq(chip, 1) < 0)
return -EIO; return -EIO;
azx_init_pci(chip); __azx_runtime_resume(chip);
hda_intel_init_chip(chip, true);
/* power down again for link-controlled chips */
if ((chip->driver_caps & AZX_DCAPS_I915_POWERWELL) &&
!hda->need_i915_power)
snd_hdac_display_power(bus, false);
snd_power_change_state(card, SNDRV_CTL_POWER_D0); snd_power_change_state(card, SNDRV_CTL_POWER_D0);
trace_azx_resume(chip); trace_azx_resume(chip);
...@@ -1045,21 +1067,14 @@ static int azx_thaw_noirq(struct device *dev) ...@@ -1045,21 +1067,14 @@ static int azx_thaw_noirq(struct device *dev)
} }
#endif /* CONFIG_PM_SLEEP */ #endif /* CONFIG_PM_SLEEP */
#ifdef CONFIG_PM
static int azx_runtime_suspend(struct device *dev) static int azx_runtime_suspend(struct device *dev)
{ {
struct snd_card *card = dev_get_drvdata(dev); struct snd_card *card = dev_get_drvdata(dev);
struct azx *chip; struct azx *chip;
struct hda_intel *hda;
if (!card) if (!azx_is_pm_ready(card))
return 0; return 0;
chip = card->private_data; chip = card->private_data;
hda = container_of(chip, struct hda_intel, chip);
if (chip->disabled || hda->init_failed)
return 0;
if (!azx_has_pm_runtime(chip)) if (!azx_has_pm_runtime(chip))
return 0; return 0;
...@@ -1067,13 +1082,7 @@ static int azx_runtime_suspend(struct device *dev) ...@@ -1067,13 +1082,7 @@ static int azx_runtime_suspend(struct device *dev)
azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) | azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) |
STATESTS_INT_MASK); STATESTS_INT_MASK);
azx_stop_chip(chip); __azx_runtime_suspend(chip);
azx_enter_link_reset(chip);
azx_clear_irq_pending(chip);
if ((chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
&& hda->need_i915_power)
snd_hdac_display_power(azx_bus(chip), false);
trace_azx_runtime_suspend(chip); trace_azx_runtime_suspend(chip);
return 0; return 0;
} }
...@@ -1082,51 +1091,18 @@ static int azx_runtime_resume(struct device *dev) ...@@ -1082,51 +1091,18 @@ static int azx_runtime_resume(struct device *dev)
{ {
struct snd_card *card = dev_get_drvdata(dev); struct snd_card *card = dev_get_drvdata(dev);
struct azx *chip; struct azx *chip;
struct hda_intel *hda;
struct hdac_bus *bus;
struct hda_codec *codec;
int status;
if (!card) if (!azx_is_pm_ready(card))
return 0; return 0;
chip = card->private_data; chip = card->private_data;
hda = container_of(chip, struct hda_intel, chip);
bus = azx_bus(chip);
if (chip->disabled || hda->init_failed)
return 0;
if (!azx_has_pm_runtime(chip)) if (!azx_has_pm_runtime(chip))
return 0; return 0;
__azx_runtime_resume(chip);
if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
snd_hdac_display_power(bus, true);
if (hda->need_i915_power)
snd_hdac_i915_set_bclk(bus);
}
/* Read STATESTS before controller reset */
status = azx_readw(chip, STATESTS);
azx_init_pci(chip);
hda_intel_init_chip(chip, true);
if (status) {
list_for_each_codec(codec, &chip->bus)
if (status & (1 << codec->addr))
schedule_delayed_work(&codec->jackpoll_work,
codec->jackpoll_interval);
}
/* disable controller Wake Up event*/ /* disable controller Wake Up event*/
azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) & azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) &
~STATESTS_INT_MASK); ~STATESTS_INT_MASK);
/* power down again for link-controlled chips */
if ((chip->driver_caps & AZX_DCAPS_I915_POWERWELL) &&
!hda->need_i915_power)
snd_hdac_display_power(bus, false);
trace_azx_runtime_resume(chip); trace_azx_runtime_resume(chip);
return 0; return 0;
} }
...@@ -1167,6 +1143,8 @@ static const struct dev_pm_ops azx_pm = { ...@@ -1167,6 +1143,8 @@ static const struct dev_pm_ops azx_pm = {
#define AZX_PM_OPS &azx_pm #define AZX_PM_OPS &azx_pm
#else #else
#define azx_add_card_list(chip) /* NOP */
#define azx_del_card_list(chip) /* NOP */
#define AZX_PM_OPS NULL #define AZX_PM_OPS NULL
#endif /* CONFIG_PM */ #endif /* CONFIG_PM */
......
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