How I Set a ThinkPad Battery Charge Threshold on Linux with TLP

AI-generated

I keep some of my ThinkPads docked for most of the day, so charging the battery to 100 percent all the time is not ideal. Linux can set a battery charge threshold on many ThinkPads, and TLP makes the setting survive a reboot.

The feature is provided by the ThinkPad firmware and exposed through the Linux kernel battery sysfs interface. TLP is just a convenient way to configure this interface permanently. It cannot add support if the hardware or firmware does not provide it.

Check if the ThinkPad supports charge thresholds

First I check which battery devices are available. Most notebooks have one internal battery called BAT0, but some ThinkPads with an additional battery can also have BAT1.

$ ls /sys/class/power_supply/
ACAD  BAT0

The important files are charge_start_threshold and charge_stop_threshold. If both files exist, the kernel can control the charging range.

$ ls /sys/class/power_supply/BAT0/charge_*_threshold
/sys/class/power_supply/BAT0/charge_start_threshold
/sys/class/power_supply/BAT0/charge_stop_threshold

I also read the current values before changing anything:

$ cat /sys/class/power_supply/BAT0/charge_start_threshold
96
$ cat /sys/class/power_supply/BAT0/charge_stop_threshold
100

A start threshold of 96 and stop threshold of 100 is basically the default behaviour. The notebook starts charging when the battery goes below 96 percent and stops at 100 percent.

Not every ThinkPad supports this. Older models sometimes need the old tp_smapi driver, while many newer models expose the sysfs files directly through thinkpad_acpi or the platform firmware. If the files do not exist, do not create them manually. TLP cannot configure a threshold in this case.

On my Arch laptops, I also make sure the thinkpad_acpi module is loaded:

$ lsmod | grep thinkpad_acpi
thinkpad_acpi          135168  0

Usually it is loaded automatically. If it is not, this can be tested without rebooting:

$ sudo modprobe thinkpad_acpi

If you have not updated the firmware in a long time, this can also be worth checking. I wrote about updating firmware from Linux before in Lenovo ThinkPad P1 UEFI BIOS Update on Linux.

Test the threshold through sysfs

Before installing or configuring TLP, I like to test the kernel interface directly. This makes it clear if a problem is related to TLP or to the notebook support itself.

For a mostly docked notebook, I normally use 75 percent as the start value and 80 percent as the stop value. This keeps the battery away from 100 percent but still leaves enough charge if I have to take the laptop with me.

$ echo 75 | sudo tee /sys/class/power_supply/BAT0/charge_start_threshold
75
$ echo 80 | sudo tee /sys/class/power_supply/BAT0/charge_stop_threshold
80

Then verify it:

$ cat /sys/class/power_supply/BAT0/charge_start_threshold
75
$ cat /sys/class/power_supply/BAT0/charge_stop_threshold
80

The exact allowed range depends on the ThinkPad model. Normally the start threshold must be lower than the stop threshold. Some firmware also has a minimum allowed value. If the write fails with Invalid argument, choose a more conservative value such as 75 and 80.

These direct sysfs changes are not persistent. After a reboot, suspend cycle or sometimes after firmware events, the original values may be active again. That is why I use TLP.

Install TLP

On Arch Linux, TLP is available as a regular package:

$ sudo pacman -S tlp

On Gentoo, the package is available as well:

# emerge --ask app-laptop/tlp

TLP handles more laptop power settings than just battery thresholds. I do not enable random options just because they exist though. My normal setup is to configure the charge threshold and leave the rest close to the defaults until I have a real reason to change something.

On systemd based distributions, I enable TLP directly after installing it:

$ sudo systemctl enable --now tlp.service
$ systemctl status tlp.service
● tlp.service - TLP system startup/shutdown
     Loaded: loaded
     Active: active (exited)

For an OpenRC Gentoo system, I use the matching service instead:

# rc-service tlp start
# rc-update add tlp default

TLP can conflict with other laptop power management services. On Arch, I check for power-profiles-daemon before enabling TLP. Running both at the same time is usually not useful and can cause confusing settings.

$ systemctl is-enabled power-profiles-daemon.service
disabled

Configure the permanent battery threshold

TLP reads its main configuration from /etc/tlp.conf. I edit it with vim, but any editor is fine.

$ sudo vim /etc/tlp.conf

The relevant lines are often present but commented out. I set them like this:

START_CHARGE_THRESH_BAT0=75
STOP_CHARGE_THRESH_BAT0=80

For a ThinkPad with a second battery, TLP supports separate settings:

START_CHARGE_THRESH_BAT1=75
STOP_CHARGE_THRESH_BAT1=80

After saving the file, I apply the configuration without rebooting:

$ sudo tlp start

Current TLP versions also provide a command to set thresholds directly. This is useful for a quick test, but I still prefer /etc/tlp.conf for the persistent configuration.

$ sudo tlp setcharge 75 80 BAT0

Verify the active settings

tlp-stat is the easiest way to see whether TLP found the battery and whether threshold support is active.

$ sudo tlp-stat -b
--- TLP 1.x --------------------------------------------

+++ Battery Care
Plugin: thinkpad
Supported features: charge thresholds
Driver usage:
* natacpi (thinkpad_acpi) = active (charge thresholds)

+++ Battery Status: BAT0
/sys/class/power_supply/BAT0/manufacturer                   = SMP
/sys/class/power_supply/BAT0/capacity                       = 78
/sys/class/power_supply/BAT0/charge_start_threshold         = 75
/sys/class/power_supply/BAT0/charge_stop_threshold          = 80

I also check the files directly after a reboot. That is the simple final test that TLP starts early enough and applies the values again.

$ cat /sys/class/power_supply/BAT0/charge_start_threshold
75
$ cat /sys/class/power_supply/BAT0/charge_stop_threshold
80

A small pitfall is testing this while the battery is already above the stop value. The notebook will correctly not charge then, but it also will not discharge itself down to 80 percent. It only starts charging again after the battery drops below the configured start threshold.

For a laptop I use on the road every day, I usually keep the default 100 percent setting. For a docked ThinkPad, 75 to 80 percent is a good compromise imho. If you change between both use cases often, tlp setcharge is quick enough to adjust.