Dell Latitude 7410 has a broken ACPI implementation
On 24-Mar-2021 01:36:40:
So last year I got a new Dell Latitude 7410 laptop at work. Recently some other coworkers were getting new laptops and they asked about this one. One specific question that I was asked was whether or not suspend to RAM worked properly. I told them it was working fine.
I was wrong, I was so wrong. Today I discovered that it only appears to work fine. The truth is that it is actually very broken in a non-obvious way.
The default behavior of suspend to RAM on most operating systems is that it automatically enters suspend on lid close and automatically resumes on lid open. If that is how you want suspend to work, then it works just fine on the laptop. Of course if you frequently close the lid on your laptop to walk to another room at work you might chose to disable this and have the laptop enter suspend only if the user explicitly tells it to. You might also set it to not wake up until the power button is explicitly pressed. These are normal user configurable settings. I'm too lazy to reinstall Windows on this laptop but I'm guessing those settings don't work right on Windows either. I'm not even sure its possible to work around this particular ACPI bug from the OS.
Lid close is an unconditional ACPI wakeup event!
Whiskey Tango Foxtrot?!? If you put the laptop in suspend to RAM and then close the lid, the laptop wakes up. I cannot fathom any situation in which this is desirable behavior.
Okay, but you can usually disable individual wakeup events from the OS. On Linux you do it in a file called /proc/acpi/wakeups
. If you cat the file you'll see a list of all the possible ACPI wakeup event triggers and whether or not each trigger is enabled. If you echo the name of one of the triggers into the file it will toggle the enable/disable state. The list is kind of big, so here are the ones that show up as enabled when Linux boots on this laptop:
RP05 S4 *enabled pci:0000:00:1c.0 PXSX S4 *enabled pci:0000:01:00.0 RP09 S4 *enabled pci:0000:00:1d.0 RP13 S4 *enabled pci:0000:00:1d.4 XHC S0 *enabled pci:0000:00:14.0 LID0 S3 *enabled platform:PNP0C0D:00 PBTN S3 *enabled platform:PNP0C0C:00
LID0 is the lid switch. This is the event you disable if you don't want your laptop automatically waking up when you open the lid. On every previous laptop I've ever used this LID0 is only a wakeup event on lid open and never on lid close. After all, why would you ever want the laptop to wake up if you're closing the lid? Okay fine if this laptop wants to be weird we can echo LID0 into the file to disable it. Thats not a big deal, I don't want a wakeup event on lid open anyway.
Except this toggle doesn't actually work! Even with it set to disabled both lid open and lid close remain ACPI wakeup events. My immediate thought was to blame Linux, but I don't think this is a bug in Linux. I went into the BIOS (which is not actually the right name for it anymore, but everyone still calls it that) which has its own options for controlling lid switch behavior. These BIOS settings also do not work which suggests that the problem lies in the firmware and is not something the OS can control.
Another indication that this is not a bug in Linux is that other events do toggle properly. I discovered that unplugging the USB-C power adapter is also an ACPI wakeup event. I traced this behavior to the RP05 event and was able to disable it from Linux. So toggling wakeup events from Linux actually does work, just not for the lid. The ACPI firmware itself must be buggy and ignores any attempt to disable wakeups on lid events.
On top of all of this Dell decided the laptop didn't need a power LED so if the lid is closed there is no clear indication of whether its still in suspend or if it woke up. I had to debug all of this using a USB mouse flipped upside down as a crude power indicator. I also tried upgrading the BIOS from 1.1.1 to 1.5.2 but that didn't help.
I'm not an ACPI expert but I have every reason to believe this is a bug in the ACPI firmware and there is nothing the OS can do about it. If this works correctly on Windows then it is only because Microsoft has some impressive workaround. Most OSes have workarounds for ACPI bugs, but I'm not aware of any way to disable an ACPI wakeup event if the firmware is ignoring the normal interface that the OS would use to do that. The only OS level workaround for bogus wakeup events that I can think of is to just immediately go back into sleep if the OS thinks that the wakeup event was bogus.
So I have no choice but to use the default Windows behavior of having lid close trigger suspend to RAM and lid open trigger resume. This is the only way to avoid the rogue ACPI wakeup event that occurs when the lid is closed. I'm okay with the latter, but I really do not want the former. Or do I... Linux is still in full control of exactly what happens when a lid close event occurs. If I want lid close to mean suspend to RAM but only during a full moon and at any other time it should say "I'm sorry Dave, I'm afraid I can't do that" over the speakers, then I can make it work that way. Or more usefully, I can make it check to see if the screen is locked.
So with my workaround in place the actual act of suspending is triggered by the lid close event, but it only happens if the screen is already locked. This allows me to carry my laptop around with the lid closed without it going to sleep and still have working suspend to RAM.