diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h index 612a17e375d0..4a85fef2eaf3 100644 --- a/include/sound/hdaudio.h +++ b/include/sound/hdaudio.h @@ -400,11 +400,13 @@ void snd_hdac_bus_process_unsol_events(struct work_struct *work); static inline void snd_hdac_codec_link_up(struct hdac_device *codec) { + dev_info(&codec->dev, "codec_powered = 1\n"); set_bit(codec->addr, &codec->bus->codec_powered); } static inline void snd_hdac_codec_link_down(struct hdac_device *codec) { + dev_info(&codec->dev, "codec_powered = 0\n"); clear_bit(codec->addr, &codec->bus->codec_powered); } diff --git a/sound/hda/hdac_bus.c b/sound/hda/hdac_bus.c index 14e57ffd5bc1..8c7115a8de0b 100644 --- a/sound/hda/hdac_bus.c +++ b/sound/hda/hdac_bus.c @@ -193,6 +193,7 @@ int snd_hdac_bus_add_device(struct hdac_bus *bus, struct hdac_device *codec) list_add_tail(&codec->list, &bus->codec_list); bus->caddr_tbl[codec->addr] = codec; + dev_info(&codec->dev, "codec_powered = 1 (add)\n"); set_bit(codec->addr, &bus->codec_powered); bus->num_codecs++; return 0; @@ -213,6 +214,7 @@ void snd_hdac_bus_remove_device(struct hdac_bus *bus, list_del_init(&codec->list); bus->caddr_tbl[codec->addr] = NULL; clear_bit(codec->addr, &bus->codec_powered); + dev_info(&codec->dev, "codec_powered = 0 (remove)\n"); bus->num_codecs--; flush_work(&bus->unsol_work); } diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 51f10ed9bc43..0d667cab628d 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -2721,18 +2721,27 @@ void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg, { hda_nid_t nid; + dev_info(&codec->core.dev, "%s: power_state = %#x\n", __func__, power_state); + for_each_hda_codec_node(nid, codec) { unsigned int wcaps = get_wcaps(codec, nid); unsigned int state = power_state; - if (!(wcaps & AC_WCAP_POWER)) + dev_info(&codec->core.dev, "%s: nid = %#hx\n", __func__, nid); + if (!(wcaps & AC_WCAP_POWER)) { + dev_info(&codec->core.dev, "%s: !(wcaps & AC_WCAP_POWER)\n", __func__); continue; + } if (codec->power_filter) { state = codec->power_filter(codec, nid, power_state); - if (state != power_state && power_state == AC_PWRST_D3) + dev_info(&codec->core.dev, "%s: after ->power_filter, state = %#x\n", __func__, state); + if (state != power_state && power_state == AC_PWRST_D3) { + dev_info(&codec->core.dev, "%s: state != power_state = %d, power_state == AC_PWRST_D3 = %d\n", __func__, state != power_state, power_state == AC_PWRST_D3); continue; + } } + dev_info(&codec->core.dev, "%s: snd_hda_codec_write() returned %d\n", __func__, snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, - state); + state)); } } EXPORT_SYMBOL_GPL(snd_hda_codec_set_power_to_all); @@ -2786,20 +2795,27 @@ static unsigned int hda_set_power_state(struct hda_codec *codec, /* repeat power states setting at most 10 times*/ for (count = 0; count < 10; count++) { - if (codec->patch_ops.set_power_state) + dev_info(&codec->core.dev, "%s: try %d\n", __func__, count); + if (codec->patch_ops.set_power_state) { + dev_info(&codec->core.dev, "%s: calling patch_ops.set_power_state()\n", __func__); codec->patch_ops.set_power_state(codec, fg, power_state); - else { + } else { state = power_state; - if (codec->power_filter) + dev_info(&codec->core.dev, "%s: initial state = %#x\n", __func__, state); + if (codec->power_filter) { state = codec->power_filter(codec, fg, state); + dev_info(&codec->core.dev, "%s: after ->power_filter(), state = %#x\n", __func__, state); + } if (state == power_state || power_state != AC_PWRST_D3) + dev_info(&codec->core.dev, "%s: snd_hda_codec_read() returned %d", __func__, snd_hda_codec_read(codec, fg, flags, AC_VERB_SET_POWER_STATE, - state); + state)); snd_hda_codec_set_power_to_all(codec, fg, power_state); } state = snd_hda_sync_power_state(codec, fg, power_state); + dev_info(&codec->core.dev, "%s: after snd_hda_sync_power_state(), state = %#x\n", __func__, state); if (!(state & AC_PWRST_ERROR)) break; } @@ -2874,6 +2890,7 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec) codec->patch_ops.suspend(codec); hda_cleanup_all_streams(codec); state = hda_set_power_state(codec, AC_PWRST_D3); + dev_info(&codec->core.dev, "%s: hda_set_power_state() returned %#x\n", __func__, state); update_power_acct(codec, true); snd_hdac_leave_pm(&codec->core); return state; @@ -2918,6 +2935,8 @@ static int hda_codec_runtime_suspend(struct device *dev) cancel_delayed_work_sync(&codec->jackpoll_work); state = hda_call_codec_suspend(codec); + dev_info(dev, "%s: hda_call_codec_suspend() returned %#x\n", __func__, state); + dev_info(dev, "%s: codec->link_down_at_suspend = %u, codec_has_clkstop=%#x, codec_has_epss = %#x, state & AC_PWRST_CLK_STOP_OK = %#x\n", __func__, codec->link_down_at_suspend, codec_has_clkstop(codec), codec_has_epss(codec), state & AC_PWRST_CLK_STOP_OK); if (codec->link_down_at_suspend || (codec_has_clkstop(codec) && codec_has_epss(codec) && (state & AC_PWRST_CLK_STOP_OK))) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 99fc0917339b..2f3e4acc0e49 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -960,24 +960,31 @@ static int param_set_xint(const char *val, const struct kernel_param *kp) /* * power management */ -static bool azx_is_pm_ready(struct snd_card *card) +static bool azx_is_pm_ready(struct device *dev, struct snd_card *card) { struct azx *chip; struct hda_intel *hda; - if (!card) + if (!card) { + dev_info(dev, "%s: !card\n", __func__); return false; + } chip = card->private_data; hda = container_of(chip, struct hda_intel, chip); - if (chip->disabled || hda->init_failed || !chip->running) + if (chip->disabled || hda->init_failed || !chip->running) { + dev_info(dev, "%s: chip->disabled=%d || hda->init_failed=%d || !chip->running=%d\n", __func__, chip->disabled, hda->init_failed, !chip->running); return false; + } return true; } -static void __azx_runtime_suspend(struct azx *chip) +static void __azx_runtime_suspend(struct device *dev, struct azx *chip) { + dev_info(dev, "%s: calling azx_stop_chip()\n", __func__); azx_stop_chip(chip); + dev_info(dev, "%s: calling azx_enter_link_reset()\n", __func__); azx_enter_link_reset(chip); + dev_info(dev, "%s: calling azx_clear_irq_pending()\n", __func__); azx_clear_irq_pending(chip); display_power(chip, false); } @@ -1018,13 +1025,13 @@ static int azx_suspend(struct device *dev) struct azx *chip; struct hdac_bus *bus; - if (!azx_is_pm_ready(card)) + if (!azx_is_pm_ready(dev, card)) return 0; chip = card->private_data; bus = azx_bus(chip); snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - __azx_runtime_suspend(chip); + __azx_runtime_suspend(dev, chip); if (bus->irq >= 0) { free_irq(bus->irq, chip); bus->irq = -1; @@ -1042,7 +1049,7 @@ static int azx_resume(struct device *dev) struct snd_card *card = dev_get_drvdata(dev); struct azx *chip; - if (!azx_is_pm_ready(card)) + if (!azx_is_pm_ready(dev, card)) return 0; chip = card->private_data; @@ -1091,17 +1098,23 @@ static int azx_runtime_suspend(struct device *dev) struct snd_card *card = dev_get_drvdata(dev); struct azx *chip; - if (!azx_is_pm_ready(card)) + if (!azx_is_pm_ready(dev, card)) { + dev_info(dev, "%s: !azx_is_pm_ready(chip)\n", __func__); return 0; + } chip = card->private_data; - if (!azx_has_pm_runtime(chip)) + if (!azx_has_pm_runtime(chip)) { + dev_info(dev, "%s: !azx_has_pm_runtime(chip)\n", __func__); return 0; + } /* enable controller wake up event */ + dev_info(dev, "%s: calling azx_writew()\n", __func__); azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) | STATESTS_INT_MASK); - __azx_runtime_suspend(chip); + __azx_runtime_suspend(dev, chip); + dev_info(dev, "%s: finished\n", __func__); trace_azx_runtime_suspend(chip); return 0; } @@ -1111,7 +1124,7 @@ static int azx_runtime_resume(struct device *dev) struct snd_card *card = dev_get_drvdata(dev); struct azx *chip; - if (!azx_is_pm_ready(card)) + if (!azx_is_pm_ready(dev, card)) return 0; chip = card->private_data; if (!azx_has_pm_runtime(chip)) @@ -1132,21 +1145,28 @@ static int azx_runtime_idle(struct device *dev) struct azx *chip; struct hda_intel *hda; - if (!card) + if (!card) { + dev_info(dev, "%s: !card\n", __func__); return 0; + } chip = card->private_data; hda = container_of(chip, struct hda_intel, chip); - if (chip->disabled || hda->init_failed) + if (chip->disabled || hda->init_failed) { + dev_info(dev, "%s: chip->disabled=%d || hda->init_failed=%d\n", __func__, chip->disabled, hda->init_failed); return 0; + } + dev_info(dev, "%s: !power_save_controller=%d || !azx_has_pm_runtime(chip)=%d || azx_bus(chip)->codec_powered=%#lx || !chip->running=%d\n", __func__, !power_save_controller, !azx_has_pm_runtime(chip), azx_bus(chip)->codec_powered, !chip->running); if (!power_save_controller || !azx_has_pm_runtime(chip) || azx_bus(chip)->codec_powered || !chip->running) return -EBUSY; /* ELD notification gets broken when HD-audio bus is off */ - if (needs_eld_notify_link(hda)) + if (needs_eld_notify_link(hda)) { + dev_info(dev, "%s: needs_eld_notify_link(hda)\n", __func__); return -EBUSY; + } return 0; }