[alsa-devel] [PATCH 2/3] ALSA: hda - WAKEEN feature enabling for runtime pm
David Henningsson
david.henningsson at canonical.com
Wed Jul 24 13:36:32 CEST 2013
On 07/24/2013 12:48 PM, Takashi Iwai wrote:
> At Tue, 23 Jul 2013 08:09:02 +0000,
> Wang, Xingchao wrote:
>>
>>>>
>>>> Signed-off-by: Wang Xingchao <xingchao.wang at linux.intel.com>
>>>> ---
>>>> sound/pci/hda/hda_intel.c | 25 +++++++++++++++++++++++++
>>>> 1 file changed, 25 insertions(+)
>>>>
>>>> diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
>>>> index 8860dd5..a7ac7fd 100644
>>>> --- a/sound/pci/hda/hda_intel.c
>>>> +++ b/sound/pci/hda/hda_intel.c
>>>> @@ -2970,6 +2970,11 @@ static int azx_runtime_suspend(struct device
>>> *dev)
>>>> {
>>>> struct snd_card *card = dev_get_drvdata(dev);
>>>> struct azx *chip = card->private_data;
>>>> + int status;
>>>> +
>>>> + /* enable controller wake up event */
>>>> + azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) |
>>>> + STATESTS_INT_MASK);
>>>>
>>>> azx_stop_chip(chip);
>>>> azx_enter_link_reset(chip);
>>>> @@ -2983,11 +2988,31 @@ static int azx_runtime_resume(struct device
>>> *dev)
>>>> {
>>>> struct snd_card *card = dev_get_drvdata(dev);
>>>> struct azx *chip = card->private_data;
>>>> + struct hda_bus *bus;
>>>> + struct hda_codec *codec;
>>>> + int status;
>>>>
>>>> if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
>>>> hda_display_power(true);
>>>> +
>>>> + /* Read STATESTS before controller reset */
>>>> + status = azx_readw(chip, STATESTS);
>>>> +
>>>> azx_init_pci(chip);
>>>> azx_init_chip(chip, 1);
>>>> +
>>>> + bus = chip->bus;
>>>> + if (status && bus) {
>>>> + list_for_each_entry(codec, &bus->codec_list, list)
>>>> + if (status & (1 << codec->addr))
>>>> + queue_delayed_work(codec->bus->workq,
>>>> + &codec->jackpoll_work,
>>> codec->jackpoll_interval);
>>>
>>> Is there a reason you want to move the jack detection to a delayed work, i e,
>>> why can't we just call:
>>>
>>> snd_hda_jack_set_dirty_all(codec);
>>> snd_hda_jack_poll_all(codec);
>>>
>>> ...from here?
>>
>> In fact it doesnot work for me, It will again call runtime_resume() and caused dead loop.
>
> It means that the power refcount is messed up by this way.
>
> When a verb is executed, the codec goes to a full resume mode, which
> turns up the controller, eventually calling azx_power_notify().
> In azx_power_notify(), pm_runtime_{get|put}_sync() is called
> accordingly, which again goes to runtime resume. A quick fix would be
> to add a flag or something to avoid reentrace.
>
> But, calling the jackpoll in the resume is basically superfluous.
> As already mentioned, issuing a verb itself triggers the full resume,
> and this already includes the update of the whole jack status.
> Thus, executing jackpoll at that place means to perform the jack
> polling twice.
>
> In other words, what's we need to achieve is just to call
> snd_hda_resume() appropriately in the runtime resume case.
> Of course, this will need more fixes for avoiding reentrance, etc.
>
> But, it leads to another question: do we need a full resume just for
> jack detection and user-space notification? Just reading the pin
> detect state should be able to run even in D3 (for chips that are
> capable of it), and the notification itself doesn't need any audio
> hardware action.
The STATESTS register only indicates which codec requested wakeup, not
which pin. So you need to issue the get_pin_sense verb for all pins on
the codec, which means that the codec - controller link must be powered up.
So that's half of the resume procedure already. Are you proposing we
introduce some kind of "half-resumed" mode that we would be in when we
wait for the response from get_pin_sense? It sounds like additional
complexity for very little gain in power.
Or am I missing something here?
--
David Henningsson, Canonical Ltd.
https://launchpad.net/~diwic
More information about the Alsa-devel
mailing list