Last updated: Fri Jul 04 2025

Lenovo Legion Battery Conservation Mode on Linux

Battery conservation mode on a Lenovo Legion limits the battery to 80% charge. This exists to handle the scenario that a laptop is plugged in for a long time where it would otherwise be kept at 100% charge, which can be harmful to the battery over the long term. Battery conservation mode is a hardware level setting (as it has to be - it needs to work while the machine is off), meaning that you can set it once and don't have to reset it again on reboot.

Battery conservation mode is exposed through the ideapad_laptop kernel module. Unfortunately, on my Lenovo Legion, this module causes occasional crashes while in sleep, so I have a slightly convoluted configuration to load ideapad_laptop on boot as usual, but unload it before sleep and reload it after sleep. This allows normal access to conservation mode while also keeping sleep mode working properly.

The relevant parts are detailed below:

Create the battery conservation mode script

This is the script which allows enabling, disabling or querying battery conservation mode.

# ~/.local/bin/bcm.sh
# (remember to chmod +x)
# -------------------
#!/usr/bin/env bash

readonly CONSERVATION_MODE_PATH='/sys/bus/platform/drivers/ideapad_acpi/VPC2004:00/conservation_mode'

readonly self=$(basename "$0")

print_usage() {
    echo $self "[option]"
    echo
    echo "      --disable   Disable battery conservation mode"
    echo "      --enable    Enable battery conservation mode"
    echo "      --status    Get battery conservation mode status"
}

get_status() {
    local status="$(cat "${CONSERVATION_MODE_PATH}")"
    if [[ "$status" -eq "1" ]]; then
        echo "Enabled"
    elif [[ "$status" -eq "0" ]]; then
        echo "Disabled"
    else
        echo "Unknown"
    fi
}

enable_bcm() {
    sudo bash -c "echo '1' > $CONSERVATION_MODE_PATH"
}

disable_bcm() {
    sudo bash -c "echo '0' > $CONSERVATION_MODE_PATH"
}

main() {
    local key="$1"

    case "${key}" in
    -d | --disable)
        disable_bcm
        ;;
    -e | --enable)
        enable_bcm
        ;;
    -h | --help)
        print_usage
        ;;
    -s | --status)
        get_status
        ;;
    *)
        echo "Invaild operation '${key}'"
        print_usage
        exit 1
        ;;
    esac
}

main "$@"

Run it with:

./bcm.sh --help
bcm.sh [option]

      --disable   Disable battery conservation mode
      --enable    Enable battery conservation mode
      --status    Get battery conservation mode status

Unload and reload ideapad_laptop on sleep and resume, respectively

Create /usr/local/sbin/reload-ideapad.sh

# /usr/local/sbin/reload-ideapad.sh
# -----------------------------------
#!/bin/bash
echo "Reloading ideapad_laptop module..."
modprobe ideapad_laptop
rfkill unblock bluetooth

The rfkill command is there because I find bluetooth doesn't always come back on otherwise.

Create /usr/local/sbin/unload-ideapad.sh

# /usr/local/sbin/unload-ideapad.sh
# ---------------------------------
#!/bin/bash
echo "Unloading ideapad_laptop module..."
modprobe -r ideapad_laptop

Create and enable the sleep service

# /etc/systemd/system/ideapad-laptop-sleep.service
# ------------------------------------------------
[Unit]
Description=Unload ideapad_laptop module before sleep and reload after resume
Before=sleep.target
StopWhenUnneeded=yes

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/sbin/unload-ideapad.sh
ExecStop=/usr/local/sbin/reload-ideapad.sh

[Install]
WantedBy=sleep.target
$ systemctl enable ideapad-laptop-sleep.service 
$ systemctl start ideapad-laptop-sleep.service