Skip to content

feat(battery)!: integrate power-policy notifications - #976

Merged
tullom merged 5 commits into
OpenDevicePartnership:mainfrom
tullom:feature/battery-power-policy
Oct 27, 2026
Merged

tullom merged 5 commits into
OpenDevicePartnership:mainfrom
tullom:feature/battery-power-policy

Conversation

@tullom

@tullom tullom commented Oct 22, 2026

Copy link
Copy Markdown
Contributor

Power-policy notifications now update each fuel gauge's external-power cache, so ACPI _PSR and _PIF report connection state and available power without taking PSU locks. Custom routing supports independent or shared sources, and the existing battery task handles notifications alongside polling.

Registrations now require a power-policy router. Updated examples and documentation cover the setup, with tests for routing, backpressure, and cancellation.

Assisted-by: GitHub Copilot:gpt-6-astra

@tullom tullom self-assigned this Oct 22, 2026
@tullom
tullom requested review from a team as code owners October 22, 2026 20:23
@tullom
tullom requested review from asasine and gjpmsft and a balanced review from Copilot October 22, 2026 20:23
@tullom tullom added enhancement New feature or request BREAKING CHANGE Marks breaking changes labels Oct 22, 2026
@tullom
tullom marked this pull request as draft October 22, 2026 20:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The _PIF mapping treats outlet-powered sources as unlimited wattage, discarding known adapter power limits.

1 open issue
What changed in this PR

This PR connects power-policy notifications to per-fuel-gauge caches, allowing battery ACPI queries to report external-power state without locking PSUs. It introduces a breaking registration requirement for power-policy routing.

Changes:

  • Add configurable routing and cached external-power state for independent or shared sources.
  • Combine notification handling with periodic battery polling, with cancellation and backpressure tests.
  • Update interfaces, examples, dependencies, and integration documentation.
File Description
tcpm-service/​src/​service/​event_receiver.rs Reuse the shared power-policy subscriber.
power-policy-interface/​src/​service/​event.rs Add a generic subscriber and forwarding tests.
power-policy-interface/​src/​psu/​mod.rs Default PSU state to detached.
examples/​std/​src/​bin/​power_policy.rs Demonstrate source-specific routing to two gauges.
examples/​std/​src/​bin/​battery.rs Combine notifications with battery polling.
examples/​std/​Cargo.lock Update example dependencies.
examples/​pico-de-gallo/​src/​bin/​battery.rs Supply the required default router.
examples/​pico-de-gallo/​Cargo.lock Update example dependencies.
Cargo.lock Record runtime and test dependencies.
battery-service/​src/​routing.rs Define routing policies and cache updates.
battery-service/​src/​registration.rs Require a router for each registration.
battery-service/​src/​lib.rs Validate and apply routed notifications.
battery-service/​src/​event_receiver.rs Combine polling and notification waits fairly.
battery-service/​src/​acpi.rs Read cached power state and add integration tests.
battery-service/​README.md Document routing, delivery, and cache semantics.
battery-service/​Cargo.toml Add async selection and test dependencies.
battery-service-relay/​src/​lib.rs Document shared-reference handler support.
battery-service-interface/​src/​lib.rs Define power-query semantics and shared-reference forwarding.
battery-service-interface/​src/​fuel_gauge.rs Store external-power state in each gauge.
battery-service-interface/​Cargo.toml Add power-policy dependency and logging features.

Review effort: Balanced

Comment thread battery-service/src/acpi.rs Outdated
Comment thread battery-service-interface/src/lib.rs Outdated
Comment thread battery-service/src/acpi.rs Outdated
@felipebalbi

Copy link
Copy Markdown
Contributor

One final thought:

I'd like us to keep connection state, energy constraints, and output capability as separate concepts, expressed through explicit domain types rather than magic integers. An outlet-powered source can still have a finite wattage limit. Note that getting there may require dedicated refactor PRs 👍

The goal is to preserve that context in the code so the next person doesn't have to rediscover it. Keep protocol encodings at the boundary, let the types enforce what they can, and document and test the relationships they can't.

Excuse the shameless plug, but I wrote about this in Making Smaller Things, Thirty-Six Registers, and Six Entries.

Comment thread power-policy-interface/src/service/event.rs
@tullom
tullom force-pushed the feature/battery-power-policy branch from c01bcff to 472bf9c Compare October 27, 2026 17:09
@tullom
tullom marked this pull request as ready for review October 27, 2026 17:18
@tullom
tullom requested review from RobertZ2011 and felipebalbi and a balanced review from Copilot October 27, 2026 17:18

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The breaking registration API and cancellation-sensitive, backpressured integration warrant final human validation despite no confirmed blocking findings.

No open issues 🎉

1 resolved since last review

Review effort: Balanced

Cache routed power-policy updates in each fuel gauge and use them for
ACPI power-source queries. Share a power-policy subscriber with TCPM
and integrate event handling into the battery examples.

BREAKING CHANGE: Registrations must provide a power-policy router;
ArrayRegistration now requires its routing type and value.

Assisted-by: GitHub Copilot:gpt-6-astra
Exercise cached ACPI power reporting, custom routing, validation,
backpressure, and cancellation. Cover subscriber forwarding and fair
polling, and enable the mock dependencies needed by these tests.

Assisted-by: GitHub Copilot:gpt-6-astra
Describe cache semantics, routing options, delivery requirements, and
polling integration. Clarify shared-reference support in the relay.

Assisted-by: GitHub Copilot:gpt-6-astra
ACPI defines the _PIF power fields as the source's rated maximums and
reserves only 0xFFFFFFFF, meaning unavailable. Power-policy
notifications carry the negotiated contract instead, and
unconstrained_power marks an outlet-powered source, not unlimited
wattage. Reporting the contract, or 0xFFFFFFFE for unconstrained
sources, misstated the rating to the host.

Report both ratings as unavailable and remove UNLIMITED_POWER_MW. The
unconstrained override now only affects _PSR. Tests check the cached
contract and unconstrained flag directly, so routing coverage no
longer depends on _PIF wattage.

Assisted-by: GitHub Copilot:claude-opus-5.5
Explain why PowerPolicySubscriber is a separate field type: composite
receivers can await it alongside other fields because each future
borrows only its own field, while &mut self helper methods on the
composite would each borrow the whole struct.

Assisted-by: GitHub Copilot:claude-opus-5.5
@tullom
tullom force-pushed the feature/battery-power-policy branch from 472bf9c to 3d10c3d Compare October 27, 2026 20:48
@tullom
tullom dismissed RobertZ2011’s stale review October 27, 2026 21:39

Addressed review comment.

@tullom
tullom enabled auto-merge (squash) October 27, 2026 21:41
@tullom
tullom merged commit 0920007 into OpenDevicePartnership:main Oct 27, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

BREAKING CHANGE Marks breaking changes enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants