Skip to content

power: supply: macsmc: add "auto-discharge" charge behaviour for CHLS - #521

Open
BoiledElectricity wants to merge 43 commits into
AsahiLinux:asahi-wipfrom
BoiledElectricity:macsmc-force-discharge-configurable
Open

power: supply: macsmc: add "auto-discharge" charge behaviour for CHLS#521
BoiledElectricity wants to merge 43 commits into
AsahiLinux:asahi-wipfrom
BoiledElectricity:macsmc-force-discharge-configurable

Conversation

@BoiledElectricity

@BoiledElectricity BoiledElectricity commented Jun 24, 2026

Copy link
Copy Markdown

Lowering the charge limit on CHLS machines always sets CHLS_FORCE_DISCHARGE, so the battery actively drains down to the limit even on AC. Per review feedback, this is now implemented as a new charge_behaviour value instead of a module parameter:

  • New auto-discharge value (enum + sysfs string + ABI doc): like auto, but actively discharge down to the charge control end threshold.
  • End-threshold writes preserve the current CHLS_FORCE_DISCHARGE bit instead of forcing it on; auto keeps its documented cap-only meaning.
  • The selection lives in the CHLS key itself: no driver state, persists across reboots, and systems upgrading from the old behaviour keep force-discharge until they explicitly write auto.

Resolves the in-code TODO. Tested on M1 MacBook Pro (j293), see comments.

The SMC firmware included in macOS 27 changed the size of BCF0 key from
4 to 1 bytes. This key is used for indicating that battery state is
critically low.

Reviewed-by: Sven Peter <sven@kernel.org>
Signed-off-by: Sasha Finkelstein <k@chaosmail.tech>
@BoiledElectricity

Copy link
Copy Markdown
Author

Tested on Apple MacBook Pro 13" M1 (j293), kernel 6.19.14, on AC at 100% (this firmware uses the CHLS path, has_chls=1):

  • force_discharge=N + set 90% limit → battery just caps charging, no discharge (Full, current_now=0)
  • force_discharge=Y (default) + set 90% limit → actively discharges (Discharging, ~-360 mA)
force_discharge=N, end_threshold=90:
  status=Full  current_now=0 uA        x4 samples over 8s

force_discharge=Y, end_threshold=90:
  status=Full         current_now=0 uA
  status=Discharging  current_now=-347000 uA
  status=Discharging  current_now=-376000 uA
  status=Discharging  current_now=-361000 uA

Battery restored to 100% / default afterwards.

jannau and others added 26 commits July 24, 2026 20:44
Certain Broadcom bluetooth chips (bcm4377/bcm4378/bcm438) need ACL
streams carrying audio to be set as "high priority" using a vendor
specific command to prevent 10-ish second-long dropouts whenever
something does a device scan. This patch sends the command when the
socket priority is set to TC_PRIO_INTERACTIVE, as BlueZ does for audio.

Signed-off-by: Sasha Finkelstein <fnkl.kernel@gmail.com>
The current approach of silently disabling all rust drivers if the
toolchain is missing results in users that try to compile their own
kernels getting a "successful" build and then being confused about where
did their drivers go. In comparison, missing openssl results in a build
failure, not a disappearance of everything that depends on it.

This also means that allyesconfig will depend on rust, but since the
rust experiment concluded with "rust is here to stay", i believe that
allyesconfig should be building rust drivers too.

Signed-off-by: Sasha Finkelstein <k@chaosmail.tech>
Apple M3 Pro and Max devices are using 'gp00' keys for GPIO in addition
to 'gP00' keys. Add a second compatible to handle this keys with an
additional macsmc-gpio instance.

Signed-off-by: Janne Grunau <j@jannau.net>
Add support for SMC GPIO keys with a lower letter 'p' via the
"apple,smc-low-gpio" compatible. This adds support for a second
macsmc-gpio controller using 'gp00' keys.
These keys are used on Apple M3 Pro and Max MacBooks in the controller
for keyboard and trackpad and for the built-in DisplayPort to HDMI
converter.

Signed-off-by: Janne Grunau <j@jannau.net>
Apple M3 Pro and Max devices are using 'gp00' keys for GPIO in addition
to 'gP00' keys. These keys are handled by an additional macsmc-gpio
instance using the "apple,smc-low-gpio" compatible.

Signed-off-by: Janne Grunau <j@jannau.net>
jannau and others added 4 commits July 24, 2026 20:51
Signed-off-by: Janne Grunau <j@jannau.net>
Signed-off-by: sofus <sofus.c@icloud.com>
Since immediate mode was enabled, unmapping a GPU VA can defer
drm_gpuvm_bo destruction until drm_gpuvm_bo_deferred_cleanup() is called.
The GEM bind and unbind paths drain that list, but Vm::drop() unmaps the
remaining user ranges without doing so.

Drain the deferred list after both teardown unmaps. Otherwise a deferred
drm_gpuvm_bo retains the imported GEM and dma-buf after its DRM file is
closed, leaving its backing pages pinned.

Fixes: 2aeee2d ("drm/asahi: Switch gpuvm to DRM_GPUVM_IMMEDIATE_MODE")
Signed-off-by: DesktopECHO <33142753+DesktopECHO@users.noreply.github.com>
Add CONFIG_VIDEO_APPLE_AVD for AVD (Apple video decoder) support.

Signed-off-by: Janne Grunau <j@jannau.net>
sofus13 and others added 9 commits July 25, 2026 22:15
Signed-off-by: sofus <sofus.c@icloud.com>
This is a hardcoded charge threshold feature present in firmware 13.0 or
newer. Userspace settings are rounded to one of the two possible
behaviors.

Since macOS Sequoia firmware, CHLS replaced CHWA and now allows an
arbitrary end charge threshold to be configured.

Prefer CHWA over CHLS since the SMC firmware from iBoot-10151.1.1
(macOS 14.0) is not compatible with our CHGLS usage. It was working
with the SMC firmware from iBoot-10151.121.1 (macOS 14.5).

Signed-off-by: Janne Grunau <j@jannau.net>
Co-developed-by: Janne Grunau <j@jannau.net>
Signed-off-by: Hector Martin <marcan@marcan.st>
Signed-off-by: Janne Grunau <j@jannau.net>
The admacs seen in M3-generation SoCs (t603x, t8122) need additional
configuration writes and so are getting a new compatible chain.

Signed-off-by: Sasha Finkelstein <k@chaosmail.tech>
Signed-off-by: Sasha Finkelstein <k@chaosmail.tech>
Signed-off-by: Sasha Finkelstein <k@chaosmail.tech>
The admacs present on t8122 and t603x SoCs need additional writes in
order to operate correctly. The exact purpose of this register
is unknown

Signed-off-by: Sasha Finkelstein <k@chaosmail.tech>
Those get a new "HF" decimator, and an extra component
that needs to be attached

Signed-off-by: Sasha Finkelstein <k@chaosmail.tech>
Signed-off-by: Janne Grunau <j@jannau.net>
@jannau

jannau commented Aug 1, 2026

Copy link
Copy Markdown
Member

Using a module option is not a good idea. It most likely will not be accepted upstream and we do not want to carry non-upstreamable patches unless they bring clear benefits.

A possible alternative solution might be to add a charge behaviour to control this. See charge_behaviour in Documentation/ABI/testing/sysfs-class-power and add either auto-discharge or auto-inhibit-discharge. I'm not sure what what the better default is from battery health perspective. Keeping the battery full charged for a long periods is not healthy but constantly charging and discharging the battery from 80% to 100% when the laptop is powered off isn't healthy either.

It would be worth checking if the charge thresholds are now respected while the laptop is powered off now that macOS has charge thresholds in 26.4 / 26.5 and later.

Signed-off-by: Sasha Finkelstein <k@chaosmail.tech>
Signed-off-by: Sasha Finkelstein <k@chaosmail.tech>
When lowering the charge-control end threshold on machines that use the
CHLS key, the driver unconditionally sets CHLS_FORCE_DISCHARGE, actively
draining the battery down to the limit even on AC power. Most laptop
charge-limit implementations instead just cap charging at the threshold
and let the battery drain naturally through use.

Add a new "auto-discharge" charge_behaviour value that opts into the
active discharge, and make end-threshold writes preserve the current
CHLS_FORCE_DISCHARGE bit instead of forcing it on. "auto" keeps its
documented meaning of only respecting the thresholds.

The selection lives in the CHLS key itself, so no state is kept in the
driver, it persists across reboots, and systems upgrading from the old
behaviour keep force-discharge enabled until they explicitly write
"auto". Resolves the existing TODO.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: James A DellaMorte <james.dellamorte@gmail.com>
@BoiledElectricity
BoiledElectricity force-pushed the macsmc-force-discharge-configurable branch from 0ed7acc to 922f0e1 Compare August 1, 2026 17:10
@BoiledElectricity BoiledElectricity changed the title power: supply: macsmc: make force-discharge to the charge limit configurable power: supply: macsmc: add "auto-discharge" charge behaviour for CHLS Aug 1, 2026
@BoiledElectricity

BoiledElectricity commented Aug 1, 2026

Copy link
Copy Markdown
Author

Reworked as suggested, I also rebased.

Tested on Apple MacBook Pro 13" M1 (j293), kernel 7.1.5-asahidev+, on AC at 96%, has_chls=1:

threshold=90, behaviour=auto:            status=Not charging  current_now=0 uA        (cap-only, x4 samples)
threshold=90, behaviour=auto-discharge:  status=Discharging   current_now=-330000 uA  (active drain)
threshold 90 -> 85:                      selection survives the threshold write
threshold -> 100 (CHLS=0x100):           no errors, firmware charges normally, selection retained
threshold -> 90 again:                   discharge resumes (-330 mA)

@jannau

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants