Contribute
Register

Help to fix sleep/wake on LID close/open

Status
Not open for further replies.
Joined
Jun 13, 2012
Messages
152
Motherboard
Lenovo Ideapad Y510P
CPU
i7 4700MQ
Graphics
HD4600
Mobile Phone
  1. Android
Hi,

I'm trying to fix sleep on LID close and wake on LID open. There are many threads/posts online about similar issues so I tried to gather as much information to get a wider idea on the problem. My system appears in my signature and almost everything is working. Especially I note power management, sleep, brightness control (so backlit works), and graphics.

Before I go on, I am aware of the patch that remove LID0._PRW. I tried it and was able to get sleep on LID close but of course wake on LID open will not work in this case at all as my understanding and also as stated in the patch. So I consider this patch as a workaround for those who can't actually fix LID+sleep/wake issues. And what I'm after is to fix both ways (if possible) without this patch.

In my DSDT, I find the _PRW returns 0x1F which corresponds to a method _L1F in _GPE so I guess this is where my attempts to fix should be. I patched my DSDT with debug methods, instrument EC queries, instrument GPE queries, instrument LID0._LID, and instrument _WAK/_PTS too.

This is the code for LID0:
Code:
    Scope (_SB)
    {
        Device (LID0)
        {
            Name (_HID, EisaId ("PNP0C0D"))  // _HID: Hardware ID
            Method (LIDX, 0, NotSerialized)  // _LID: Lid Status
            {
                Notify (^^PCI0.PEG0.PEGP, 0xDB)
                Return (GP15)
            }

            Name (_PRW, Package (0x02)  // _PRW: Power Resources for Wake
            {
                0x1F, 
                0x03
            })
            Method (_LID, 0, NotSerialized)
            {
                \rmdt.p1("LID0._LID enter")
                Store(LIDX(), Local0)
                \rmdt.p2("LID0._LID returning", Local0)
                Return(Local0)
            }
        }
    }

And this is the code for method _GPE._L1F:
Code:
Method (_L1F, 0, NotSerialized)  // _Lxx: Level-Triggered GPE
        {
            \rmdt.p1("GPE _L1F enter")
If (GP15)
            {
                Or (GIV1, 0x80, GIV1)
            }
            Else
            {
                And (GIV1, 0x7F, GIV1)
            }

            If (IGDS)
            {
                If (\_SB.PCI0.IGPU.GLID (LAnd (GIV1, 0x80)))
                {
                    Or (0x80000000, \_SB.PCI0.IGPU.CLID, \_SB.PCI0.IGPU.CLID)
                }
            }

            Notify (\_SB.LID0, 0x80)
\rmdt.p1("GPE _L1F exit")

        }

I'm not sure where to start from since without Remove LID0._PRW patch both ways are broken. But as a start here's a scenario:

1. I booted without Remove LID0._PRW patch
2. I put the system to sleep manually (while closing the LID before it sleeps completely)
3. System went to sleep but automatically woke up because of the LID:
Code:
12/04/2015 21:35:53.000 kernel[0]: Wake reason: LID0
4. After system woke up backlit did not work
5. I put it to sleep again using keyboard shortcut then woke it up with a keystroke. Backlit worked this time.

This is the logs for the whole process:
Code:
12/04/2015 21:36:45.000 kernel[0]: ACPIDebug: { "_PTS enter", 0x3, }
12/04/2015 21:36:45.000 kernel[0]: ACPIDebug: { "_PTS enter", 0x3, }
12/04/2015 21:36:45.000 kernel[0]: ACPIDebug: "_PTS exit"
12/04/2015 21:36:45.000 kernel[0]: ACPIDebug: "_PTS exit"
12/04/2015 21:36:45.000 kernel[0]: ACPIDebug: { "_WAK enter", 0x3, }
12/04/2015 21:36:45.000 kernel[0]: ACPIDebug: { "_WAK enter", 0x3, }
12/04/2015 21:36:45.000 kernel[0]: ACPIDebug: "_WAK exit"
12/04/2015 21:36:45.000 kernel[0]: ACPIDebug: "_WAK exit"
12/04/2015 21:36:45.000 kernel[0]: ACPIDebug: "LID0._LID enter"
12/04/2015 21:36:45.000 kernel[0]: ACPIDebug: { "LID0._LID returning", 0x1, }
12/04/2015 21:36:45.000 kernel[0]: ACPIDebug: "LID0._LID enter"
12/04/2015 21:36:45.000 kernel[0]: ACPIDebug: { "LID0._LID returning", 0x1, }
12/04/2015 21:36:45.000 kernel[0]: ACPIDebug: "GPE _L1E enter"
12/04/2015 21:36:45.000 kernel[0]: ACPIDebug: "EC _Q25 enter"
12/04/2015 21:36:45.000 kernel[0]: ACPIDebug: "GPE _L1E enter"
12/04/2015 21:36:47.000 kernel[0]: ACPIDebug: "EC _Q25 exit"

I see no mention here for GPE _L1F but no much of work with LID happened in the scenario anyway. When I apply the Remove LID0._PRW patch I see GPE _L1F enter but not exit and of course no wake on LID open.



EDIT:

I tried with the poll for LID changes patch (and ACPIPoller.kext). The system was able to sleep on LID close but immediately woke up and wake reason was LID0. I think this is better than removing _PWR as it allows a working sleep with the possibility to fix wake on LID, if I'm not wrong though.


I'm attaching the IOREG and my native DSDT ..


Thanks in advance
 

Attachments

  • ahmed_ais.ioreg.zip
    1.3 MB · Views: 131
  • DSDT.aml.zip
    18 KB · Views: 118
I think your best bet is to remove _PRW and wake the laptop via means other than the lid.

If we knew what caused that "instant wake", we would be able to fix both this issue and the instant wake caused by USB. I keep searching, but haven't found an answer. Clearly, Windows initializes something differently from OS X that causes this wake. Removing all _PRW (or having them return 0 for the sleep mode) that correspond to a particular _GPE wake is a reasonable work around, even if it disables wake on that event.
 
Thanks for the clarification.

There is one more thing I would like to say about this. I said before I found the _PRW for LID0 returns 0x1F which corresponds to the method _GPE._L1F. I tried to change the value _PRW returns to 0x01 (and no reason for the choice). I found the system was able to sleep on LID close as well.

The method _GPE._L01 happen to exist but it does not have anything related to LID. Can I assume that sleep worked because the code in _GPE._L1F has not been triggered the same way by removing _PRW? I would assume this is dangerous as calling the code in _GPE._L01 in the wrong time / situation is not right. Am I correct on my assumptions? What do you see in this?

Thanks.
 
Thanks for the clarification.

There is one more thing I would like to say about this. I said before I found the _PRW for LID0 returns 0x1F which corresponds to the method _GPE._L1F. I tried to change the value _PRW returns to 0x01 (and no reason for the choice). I found the system was able to sleep on LID close as well.

Of course. _PRW and _GPE._L1F has to do with triggering wake, not sleep.

The method _GPE._L01 happen to exist but it does not have anything related to LID.

The code you presented in post #1 has everything to do with the lid. See Notify.

Can I assume that sleep worked because the code in _GPE._L1F has not been triggered the same way by removing _PRW?

I believe that by removing all _PRW objects that return a given reference to a GPE bit, it effectively causes that GPE to be masked by the system, such that it no longer has the ability to wake the computer.

I would assume this is dangerous as calling the code in _GPE._L01 in the wrong time / situation is not right. Am I correct on my assumptions? What do you see in this?

_GPE._L01 is called by the system upon wake. Generally, it is not called directly as it doesn't make much sense (think of it as an event handler)
 
Of course. _PRW and _GPE._L1F has to do with triggering wake, not sleep.
Yea I'm still reading about ACPI specs so it will take some time to learn which is doing what exactly.

The code you presented in post #1 has everything to do with the lid. See Notify.
Yes indeed. However, the code in post #1 is not related to the test with 0x01 return for _PRW. I mentioned this attempt on post #3 without any associated results just for sharing the idea.

I used to remove _PRW for EHC1/EHC2/XHC to fix instant-wake from sleep but those does not have any uncontrollable side effect and removing _PRW for them does not break any thing else. This one, however, have apparent side effect as fixing LID sleep will break LID wake. So I think I will take your advice on post #2 until something is discovered as of why the instant-wake exactly happen.

Thanks for your time and help.
 
...Yes indeed. However, the code in post #1 is not related to the test with 0x01 return for _PRW. I mentioned this attempt on post #3 without any associated results just for sharing the idea.

I already explained that _PRW and _L1F has nothing to do with triggering sleep via the lid. Lid sleep is triggered when the ACPI _LID method returns an indication that the lid is closed. See ACPI spec.

I used to remove _PRW for EHC1/EHC2/XHC to fix instant-wake from sleep but those does not have any uncontrollable side effect and removing _PRW for them does not break any thing else. This one, however, have apparent side effect as fixing LID sleep will break LID wake.

There are the same side effects... Removing _PRW for EHC*/XHC has the side effect of breaking "wake on USB"...
 
There are the same side effects... Removing _PRW for EHC*/XHC has the side effect of breaking "wake on USB"...

Yea I understand this. But I never thought of waking my computer by using a USB device or even allowing that assuming the feature exist and working. So it does not harm if this is broken with removing _PRW for EHC*/XHC as it is for LID0 (it is not a big problem anyway).
 
Yea I understand this. But I never thought of waking my computer by using a USB device or even allowing that assuming the feature exist and working. So it does not harm if this is broken with removing _PRW for EHC*/XHC as it is for LID0 (it is not a big problem anyway).

No harm that I can see. I actually prefer no wake on USB. But I'm happy that wake on lid works on my Lenovo u430.
 
Status
Not open for further replies.
Back
Top