aports: add fp6-charging-mode (offline charging, charger-boot detection)

Charger-insertion boots (androidboot.mode=charger, ABL-appended) divert to
a minimal charging.target instead of the full UI, ending the dead-battery
bootloop: ADSP charging/USB-PD runs, splash+panel killed ~6-10s in via an
initramfs hook, modem+cdsp stopped, radios/sensors suppressed, CPU capped.
Power key reboots to a normal boot, volume-up shows battery status,
volume-down enables USB ssh, unplug powers off. Measured >= breakeven on a
100mA-classified SDP port, strongly net-positive on real chargers.

Suspend duty-cycling (~13mA floor) exists behind an off-by-default flag:
resume from deep suspend intermittently kills the UFS link (hibern8 exit
failed ret=5) - do not enable until that kernel bug is fixed.

Byte-identical to the deployment verified on the dev phone 2026-08-24
(journal/power: r5 armed tests, crash autopsies, measurements).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Jorijn van der Graaf 2026-08-24 04:03:06 +02:00
commit eb13c18ea8
12 changed files with 507 additions and 1 deletions

View file

@ -0,0 +1,26 @@
# Offline charging mode: minimal boot target for charger-triggered boots.
# Reached only via charging-mode-generator (never enabled, never the static
# default). basic.target gives us udev coldplug -> qcom_q6v5_pas module ->
# ADSP boot -> pmic_glink/battmgr (all builtin), i.e. battery telemetry and
# the ADSP-owned charging state machine, with no UI stack and no greeter.
#
# systemd-logind handles the power key (generator drops HandlePowerKey=reboot
# into /run for this boot only).
[Unit]
Description=Offline charging mode
Requires=basic.target
After=basic.target rescue.service rescue.target
Conflicts=rescue.service rescue.target
Wants=charging-monitor.service systemd-logind.service
AllowIsolate=yes
# Observability (r3): ssh is OFF by default — volume-down enables it
# (charging-keys starts systemd-user-sessions + charging-usbnet + sshd, USB
# cable only, no NetworkManager/wifi ever). systemd-user-sessions is needed
# at that moment because we bypass multi-user.target and sshd would
# otherwise refuse unprivileged logins via pam_nologin.
# Radios/sensors are kept out via ConditionPathExists drop-ins on
# bluetooth/iio-sensor-proxy/hkdm (marker: /run/charging-mode) and the
# monitor stops the modem + cdsp remoteprocs.
Wants=charging-keys.service