Skip to content

platform/surface: add SP11 platform profile and low-power cap - #91

Draft
ooaklee wants to merge 3 commits into
jglathe:jg/ubuntu-qcom-x1e-7.2.yfrom
ooaklee:x/sp11-platform-profile
Draft

platform/surface: add SP11 platform profile and low-power cap#91
ooaklee wants to merge 3 commits into
jglathe:jg/ubuntu-qcom-x1e-7.2.yfrom
ooaklee:x/sp11-platform-profile

Conversation

@ooaklee

@ooaklee ooaklee commented Sep 1, 2026

Copy link
Copy Markdown

Summary

  • keep the platform-profile class available to device-tree providers when ACPI is disabled at runtime
  • instantiate the existing Surface profile and fan-speed devices for Surface Pro 11
  • apply an SP11-only 2.515 GHz CPU-frequency ceiling while the low-power profile is selected

Dependency and status

This PR targets jg/ubuntu-qcom-x1e-7.2.y directly and is the final contained platform-profile topic in the ordered SP11 extraction:

The branch is based directly on the current release branch, including the volume-key work merged through #82. It does not merge the #90 prerequisite head, the broad -sp11 staging branch, or #81's staging-fix branch.

The battery topic and this topic both edit ssam_node_group_sp11. This direct-base branch keeps the platform-profile diff independently reviewable, but it must be rebased/re-lifted after #90 merges. That re-lift must preserve both battery-provider omissions from #90 as well as the profile and fan additions here before this PR can leave draft status.

This PR is a draft because it touches shared platform-profile framework code and requires the SP11 and cross-device checks below before it is ready.

Containment

  • with CONFIG_ACPI=y, the platform-profile class remains available to device-tree providers when ACPI is disabled at runtime, including an acpi=off boot; the legacy ACPI attribute group is still created only when ACPI has initialized successfully and its kobject is available
  • CONFIG_ACPI=n is not a supported build case for this change: both ACPI_PLATFORM_PROFILE and SURFACE_PLATFORM_PROFILE are selected from ACPI-dependent Kconfig paths, so relocating those subsystems is outside this topic
  • legacy ACPI notifications and teardown are guarded by the recorded attribute-group state
  • profile and fan nodes are added only to the Denali Surface registry group
  • CPU-frequency QoS is allocated only when a device supplies the low-power-max-frequency-khz property
  • that property and the default low-power selection are present only on the SP11 software node
  • existing Surface devices without the property retain the legacy TMP-then-fan write order, including same-profile writes; they do not enter the new readback transaction and allocate no QoS request
  • existing online CPU policies are replayed when the SP11 QoS tracker starts, followed by a second online-CPU scan to close the replay-to-live-hotplug handoff; live CPU hotplug can also recover the current policy when no replay reference is available
  • CPU-frequency CREATE and REMOVE notifications track policy lifetime, and stored raw policy pointers are cleared synchronously during REMOVE before the CPU-frequency core can free them
  • teardown first prevents new policy attachment, removes the CPU-hotplug instance and dynamic state, sweeps QoS requests and policy slots while the REMOVE notifier is still registered, and unregisters the notifier last
  • if CPU frequency is unavailable, including a cpufreq.off=1 boot or notifier-registration failure, only the optional frequency cap is disabled; platform-profile and fan control remain registered
  • entering low power applies the CPU cap first, then fan state, and writes TMP last; leaving low power applies fan state first, writes TMP, and releases the cap last
  • TMP remains authoritative: a failed transition reads the resulting TMP profile back and reconciles fan and cap state to it; an uncertain readback, or failed fan reconciliation involving low power, retains the conservative low-power cap
  • the staging branch's no-op power-supply notifier is not carried

Provenance

All three focused rewrites are authored by Leon Silcott, retain immutable links to their corresponding integration commits, and carry the authorized Signed-off-by: Leon Silcott <leon@boasi.io>.

Validation

  • git diff --check e3bd10a401d9..HEAD
  • ARM64 ubuntu_x1e_defconfig W=1 builds, with 10 jobs, of drivers/acpi/platform_profile.o, drivers/platform/surface/surface_aggregator_registry.o, and drivers/platform/surface/surface_platform_profile.o
  • the same three W=1 object targets build with 10 jobs and CONFIG_CPU_FREQ=n, covering the optional QoS path
  • strict checkpatch passes independently on each of the three final rewritten commits with 0 errors, 0 warnings, and 0 checks
  • lifecycle audit covers failed ACPI initialization, class registration, legacy attribute creation, notification, and teardown
  • QoS audit covers policies present at probe, policies created later, fully offline policies, policy removal, profile-device removal, and property absence
  • transition audit covers cap/fan/TMP ordering, post-error TMP readback, fan reconciliation, and conservative capping when state cannot be established safely
  • non-SP11 source audit confirms the exact legacy write path and no frequency-cap, default-profile, or transaction change without the Denali-only software-node properties

These are targeted object-build checks. They do not claim a complete kernel package build or a successful standalone module/modpost pass.

Userspace integration

Ubuntu Resolute's stock Power Profiles Daemon 0.30-2 probes only the legacy /sys/firmware/acpi/platform_profile and /sys/firmware/acpi/platform_profile_choices paths. It does not discover the native /sys/class/platform-profile provider added here.

Direct native-sysfs testing is therefore available with this kernel alone, but desktop integration and powerprofilesctl require the pinned companion userspace change or an equivalent backport. That userspace combination must be tested before this PR is marked ready.

Hardware checks still required

  • boot this exact branch on both X1E/OLED and X1P/LCD Surface Pro 11 variants and verify the native platform-profile class and fan-speed device enumerate
  • on both variants, verify the advertised profile choices, default low-power selection, fan behavior, and the 2.515 GHz ceiling
  • switch repeatedly among low-power, balanced, and performance profiles under load, confirming the cap reaches every CPU policy in low power and is released everywhere on exit
  • fully offline every CPU in one policy, select low power while that policy is absent, bring it online again, and verify the cap is attached; repeat while leaving low power
  • bind and unbind the Surface platform-profile driver repeatedly, checking for stale QoS requests, missing policies, warnings, or use-after-free reports
  • tear down and re-register CPU-frequency policies while the profile driver remains bound, in both capped and uncapped profiles
  • boot with cpufreq.off=1 and confirm profile selection and fan control still work while no frequency cap is advertised or attempted
  • fault-inject TMP writes, fan writes, TMP readback, and fan reconciliation; verify recovered state follows readable TMP and uncertain low-power transitions keep the conservative cap
  • suspend and resume in each profile, then repeat transitions, workload, and fully-offline-policy checks
  • test direct native sysfs and the pinned companion userspace/backport separately, including desktop controls and powerprofilesctl
  • exercise a non-SP11 Surface with an existing SAM platform-profile provider and confirm same-profile writes, profiles, legacy ACPI interface, fan behavior, and CPU-frequency limits remain unchanged

Device-tree systems can use platform-profile providers even when ACPI is
disabled, but the framework currently declines to register its class in
that case. Register the class unconditionally and create the legacy ACPI
attribute group only after ACPI has initialized successfully.

Record that group registration and use it to guard legacy notifications
and teardown. This keeps the class path independent of ACPI while also
avoiding a stale acpi_kobj after an ACPI initialization failure.

This exposes the native /sys/class/platform-profile/ interface without
creating a synthetic /sys/firmware/acpi hierarchy. Existing ACPI systems
retain the legacy aggregate attributes unchanged.

This is a contained rework of the original SP11 non-ACPI enablement.

Link: 106ad0d
Signed-off-by: Leon Silcott <leon@boasi.io>
The Surface Pro 11 has active cooling and supports SAM performance
profiles, but its registry group does not instantiate the existing
platform-profile and fan-speed devices.

Add the existing fan-capable profile node and fan-speed node only to the
Denali software-node group. Other Surface device groups are unchanged.

Link: 5c513ff
Signed-off-by: Leon Silcott <leon@boasi.io>
The Surface Pro 11 needs a lower CPU-frequency ceiling in its
low-power profile to match the validated cool-running baseline.
Describe the 2.515 GHz ceiling and default low-power selection on an
SP11-only software node.

Set up frequency-QoS only when that per-device property is present.
Devices without it retain the legacy TMP-then-fan write order,
including writes that repeat the current profile.

Track cpufreq policies through CREATE and REMOVE notifications plus a
per-device CPU-hotplug state, so a policy that is fully offline at
probe is capped when a CPU returns. Hold policy references while
attaching requests, clear stored raw pointers synchronously on REMOVE,
and stop hotplug callbacks before tearing down requests and the
notifier.

When entering low power, apply the cap before fan and TMP changes; when
leaving, restore fan and TMP before dropping the cap. If a SAM write
fails, read TMP back and reconcile fan and cap conservatively. An
unavailable cpufreq subsystem degrades to profile-only operation.

Omit the staging implementation’s no-op power-supply notifier. This is
a contained rework of the original SP11 low-power implementation.

Link: 30972bd

Signed-off-by: Leon Silcott <leon@boasi.io>
ooaklee added a commit to ooaklee/linux_ms_dev_kit-sp11 that referenced this pull request Sep 1, 2026
Integrate jglathe#91 for combined SP11 testing.

Resolve the jglathe#90 prerequisite overlap by retaining the Denali-scoped battery-provider omissions alongside the profile and fan nodes.

Signed-off-by: Leon Silcott <leon@boasi.io>
@jglathe
jglathe force-pushed the jg/ubuntu-qcom-x1e-7.2.y branch from 87bcf07 to 4943ee7 Compare September 3, 2026 10:32
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.

1 participant