Getting suspend in Linux working on a MacBook Pro


2 min read
linux

A lot of my distro hopping as of late has been due to my inability to get my daily driver, a MacBook Pro 12,1 (2015) to suspend correctly.

Each distro resulted in the same. Close the lid, the Apple logo goes dark and within a few seconds, it lights back up.

If I am in a hurry and didn’t realize it, the system would hang out in my laptop bag and run super hot until the battery runs out.

BUT NO MORE!

As of my recent switch to Debian Stretch (Testing, and currently on a full freeze), I have been able to get suspend working properly!

That’s not to say that Debian worked better out of the box than the four other distributions I have used recently. I do feel that the shear volume of documentation that’s out there for Debian is what finally allowed me to find the appropriate information to concoct a fix.

So what was the culprit? Turns out it’s something funky with USB 3.0 ports that end up waking up the machine immediately after it goes to sleep. I was able to disable the USB event and all started to work as expected.

To check and see if you have USB 3.0 on your system, run lsusb and look for a line like this:

Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub

If you’re on USB 3.0, you’ll see a 3.0 in there. Otherwise, you’ll see whatever USB version your system has.

You can follow up that command with cat /proc/acpi/wakeup which will list the devices with wakeup events and whether or not they are enabled.

On my system I had a few things enabled. The device for the USB port(s) is XHC1. You can try disabling it by running the following:

echo XHC1 > /proc/acpi/wakeup

Note, I had read that the lid can play some tricks as well. If you want to disable the lid as well, you can run this:

echo LID0 > /proc/acpi/wakeup

If you disable the lid, you’ll need to hit the power button to resume.

At this point, everything should be working as expected. Only issue is that the commands we just ran aren’t persistent and will need to be run after every boot. The quick fix is to dump those commands into /etc/rc.local. It should look something like this:

#!/bin/sh -e
echo LID0 > /proc/acpi/wakeup
echo XHC1 > /proc/acpi/wakeup
exit 0

You could also go through the trouble of setting up a systemd service, if you’re into that ;)