Skip to content

Enable deep suspend on SM8550 and drop the Pocket EVO fan tacho IRQ - #23

Closed
jesherman wants to merge 1 commit into
armada-os:mainfrom
jesherman:feat/sm8550-deep-suspend-evo
Closed

Enable deep suspend on SM8550 and drop the Pocket EVO fan tacho IRQ#23
jesherman wants to merge 1 commit into
armada-os:mainfrom
jesherman:feat/sm8550-deep-suspend-evo

Conversation

@jesherman

@jesherman jesherman commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Makes suspend-to-RAM hold on the AYANEO Pocket EVO. Doesn't switch any device to it — that's armada#215.

Changes

Six patches from ROCKNIX #2954 — TSENS wake IRQs, geni UART, UFS resume races. Four of that PR's patches omitted: 0502 already carried as 0504; 1004 is for a gamepad driver the EVO doesn't use; 1007/1015 don't apply to 7.1.5 (kept as files, commented out in series).

Fan tacho DTS override — not covered upstream, whose SM8550 testing was on a Retroid Pocket 6. pocket-common.dtsi gives pwm-fan an edge-falling IRQ on TLMM GPIO 64; it fires ~80×/sec while the fan spins and repeatedly pulls the SoC out of suspend (/proc/interrupts passed 230,000). The Odin 3 declares none and sleeps for hours. Scoped to the EVO .dts, not the DTSI six other boards include. Costs fan1_input RPM reporting, as on the Odin 3.

PM_DEBUG/PM_SLEEP_DEBUG/GENERIC_IRQ_DEBUGFSpm_wakeup_irq is what made this diagnosable. Easy to drop if you'd rather not ship debug options.

Results

Pocket EVO, battery, Steam running: 1202s deep suspend woken only by the RTC alarm, success=3 fail=0. Standby 27.8 mA vs 161.8 mA — 5.8× lower, ~2 days to ~12.

From the 7.0.11 build. 7.1.5 confirmed working (session running, clean resume) but only a ~4 min run.

Caveat: version-fragile

Three of eight patches broke moving 7.0.11 → 7.1.5. 0201 is the risk — only UFS-core patch, 424 lines in ufshcd.c, tracking ufshcd_intr(), which 7.2 changes again by reverting the threaded IRQ handler. Re-derive rather than rebase next bump. Dropping it hangs resume with Steam running, so it's load-bearing here.

Testing

Pocket EVO, 7.1.5, 125 patches applied / 0 failed. Untested on other AYANEO Pockets; DTS change is EVO-scoped, kernel patches are qcom,sm8550-guarded or Qualcomm-generic.

🤖 Generated with Claude Code

The AYANEO Pocket EVO cannot hold suspend-to-RAM. Measured on device it
leaves deep suspend after 2-92s, and with a Steam session running it fails
to resume at all and needs a hard reset. It ships ARMADA_SUSPEND_MODE=fake
as a result, which costs about 162mA of standby drain.

Two independent causes.

The first is SoC-wide and already solved upstream. ROCKNIX PR #2954 (and
jaewun's #2952 before it) fixes the SM8550 wake sources and UFS resume
races: TSENS passive threshold IRQs armed for wake, a geni UART IRQ left
unmasked across suspend, and a set of UFS hibern8/link-recovery races. Six
of those patches are picked up here. Four are left out: 0502 (qcom-ipcc
IRQF_NO_SUSPEND) is already carried as 0504, 1004 (rsinput MCU resume)
targets a gamepad driver the EVO does not use, and 1007/1015 do not apply
to 7.1.5. Deep suspend was validated without 1007/1015.

The second cause is specific to the AYANEO Pockets and is not covered
upstream, whose SM8550 testing was on a Retroid Pocket 6. pocket-common.dtsi
declares an edge-falling tacho interrupt on TLMM GPIO 64 for pwm-fan. It
fires ~80 times a second whenever the fan spins and repeatedly pulls the SoC
back out of deep suspend; /proc/interrupts showed it climbing past 230,000.
The Odin 3 declares no tacho interrupt and suspends for hours. It is
overridden in the EVO .dts rather than the shared DTSI, which six other
boards include. Cost: hwmon fan1_input stops reporting RPM, as on the Odin 3.

Also enable the PM and IRQ debug options. Diagnosing this without
pm_wakeup_irq meant guessing at wake sources across a dozen hard resets;
with them the offending IRQ names itself. That is how the fan tacho was
found: /sys/kernel/debug/irq/irqs/<n> "wdepth" shows what is armed for wake.

Measured on a Pocket EVO, on battery with Steam running: 1202s of
uninterrupted deep suspend woken only by the RTC alarm, and standby drain of
27.8mA against 161.8mA for fake suspend - 5.8x lower, roughly 2 days of
standby to 12. Those numbers are from the 7.0.11 build; 7.1.5 was then
confirmed to hold deep suspend with the session running and resume cleanly.

Note this set is version-fragile. Three of the eight patches broke moving
from 7.0.11 to 7.1.5, and 0201 touches ufshcd_intr(), which 7.2 changes
again by reverting the threaded IRQ handler. Plan to re-derive it rather
than rebase on the next kernel bump.

This only makes deep suspend work; it does not switch any device over to it.
ARMADA_SUSPEND_MODE stays 'fake' everywhere until this has had a longer soak.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@jesherman

Copy link
Copy Markdown
Contributor Author

moving to draft as im getting inconsistent perf.

@jesherman

jesherman commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

no worries i completely agree. I'm still testing this as I found some intermittent performance issues/failure to wake and I do think there are some additional wrinkles here.

Happy to pull a separate PR just for the fan DTS override

@virtudude

Copy link
Copy Markdown
Member

no worries i completely agree. I'm still testing this as I found some intermittent performance issues/failure to wake and I do think there are some additional wrinkles here.

Happy to pull a separate PR just for the fan DTS override

Yikes just realized Claude commented on this while I was having it inventory open PRs 🙃

But I (a human) agree with holding on this for now.

xiaodoudou pushed a commit to xiaodoudou/distribution that referenced this pull request Aug 6, 2026
qcs8550-ayaneo-pocket-common.dtsi gives pwm-fan an edge-falling TLMM 64
interrupt for the tachometer. Measured on a Pocket EVO it fires about 80
times a second whenever the fan spins and repeatedly pulls the SoC back
out of deep suspend, with /proc/interrupts climbing past 230,000; with
the fan stopped the same suspend holds. The AYN Odin 3 declares no tacho
interrupt and suspends for hours.

Overridden in the EVO .dts rather than in the shared DTSI, which six
other boards include and whose fan wiring has not been checked. Cost:
hwmon fan1_input stops reporting RPM, as on the Odin 3.

Found and measured by jesherman in armada-os/armada-packages#23. The EVO
stays outside the device gate; this removes one of the two reasons it is
there.
@jesherman

Copy link
Copy Markdown
Contributor Author

replaced by #28

@jesherman jesherman closed this Aug 6, 2026
xiaodoudou pushed a commit to xiaodoudou/distribution that referenced this pull request Aug 7, 2026
qcs8550-ayaneo-pocket-common.dtsi gives pwm-fan an edge-falling TLMM 64
interrupt for the tachometer. Measured on a Pocket EVO it fires about 80
times a second whenever the fan spins and repeatedly pulls the SoC back
out of deep suspend, with /proc/interrupts climbing past 230,000; with
the fan stopped the same suspend holds. The AYN Odin 3 declares no tacho
interrupt and suspends for hours.

Overridden in the EVO .dts rather than in the shared DTSI, which six
other boards include and whose fan wiring has not been checked. Cost:
hwmon fan1_input stops reporting RPM, as on the Odin 3.

Found and measured by jesherman in armada-os/armada-packages#23. The EVO
stays outside the device gate; this removes one of the two reasons it is
there.
xiaodoudou pushed a commit to xiaodoudou/distribution that referenced this pull request Aug 8, 2026
qcs8550-ayaneo-pocket-common.dtsi gives pwm-fan an edge-falling TLMM 64
interrupt for the tachometer. Measured on a Pocket EVO it fires about 80
times a second whenever the fan spins and repeatedly pulls the SoC back
out of deep suspend, with /proc/interrupts climbing past 230,000; with
the fan stopped the same suspend holds. The AYN Odin 3 declares no tacho
interrupt and suspends for hours.

Overridden in the EVO .dts rather than in the shared DTSI, which six
other boards include and whose fan wiring has not been checked. Cost:
hwmon fan1_input stops reporting RPM, as on the Odin 3.

Found and measured by jesherman in armada-os/armada-packages#23. The EVO
stays outside the device gate; this removes one of the two reasons it is
there.
xiaodoudou pushed a commit to xiaodoudou/distribution that referenced this pull request Aug 10, 2026
qcs8550-ayaneo-pocket-common.dtsi gives pwm-fan an edge-falling TLMM 64
interrupt for the tachometer. Measured on a Pocket EVO it fires about 80
times a second whenever the fan spins and repeatedly pulls the SoC back
out of deep suspend, with /proc/interrupts climbing past 230,000; with
the fan stopped the same suspend holds. The AYN Odin 3 declares no tacho
interrupt and suspends for hours.

Overridden in the EVO .dts rather than in the shared DTSI, which six
other boards include and whose fan wiring has not been checked. Cost:
hwmon fan1_input stops reporting RPM, as on the Odin 3.

Found and measured by jesherman in armada-os/armada-packages#23. The EVO
stays outside the device gate; this removes one of the two reasons it is
there.
xiaodoudou pushed a commit to xiaodoudou/distribution that referenced this pull request Aug 11, 2026
qcs8550-ayaneo-pocket-common.dtsi gives pwm-fan an edge-falling TLMM 64
interrupt for the tachometer. Measured on a Pocket EVO it fires about 80
times a second whenever the fan spins and repeatedly pulls the SoC back
out of deep suspend, with /proc/interrupts climbing past 230,000; with
the fan stopped the same suspend holds. The AYN Odin 3 declares no tacho
interrupt and suspends for hours.

Overridden in the EVO .dts rather than in the shared DTSI, which six
other boards include and whose fan wiring has not been checked. Cost:
hwmon fan1_input stops reporting RPM, as on the Odin 3.

Found and measured by jesherman in armada-os/armada-packages#23. The EVO
stays outside the device gate; this removes one of the two reasons it is
there.
xiaodoudou pushed a commit to xiaodoudou/distribution that referenced this pull request Aug 22, 2026
qcs8550-ayaneo-pocket-common.dtsi gives pwm-fan an edge-falling TLMM 64
interrupt for the tachometer. Measured on a Pocket EVO it fires about 80
times a second whenever the fan spins and repeatedly pulls the SoC back
out of deep suspend, with /proc/interrupts climbing past 230,000; with
the fan stopped the same suspend holds. The AYN Odin 3 declares no tacho
interrupt and suspends for hours.

Overridden in the EVO .dts rather than in the shared DTSI, which six
other boards include and whose fan wiring has not been checked. Cost:
hwmon fan1_input stops reporting RPM, as on the Odin 3.

Found and measured by jesherman in armada-os/armada-packages#23. The EVO
stays outside the device gate; this removes one of the two reasons it is
there.
xiaodoudou pushed a commit to xiaodoudou/distribution that referenced this pull request Aug 23, 2026
qcs8550-ayaneo-pocket-common.dtsi gives pwm-fan an edge-falling TLMM 64
interrupt for the tachometer. Measured on a Pocket EVO it fires about 80
times a second whenever the fan spins and repeatedly pulls the SoC back
out of deep suspend, with /proc/interrupts climbing past 230,000; with
the fan stopped the same suspend holds. The AYN Odin 3 declares no tacho
interrupt and suspends for hours.

Overridden in the EVO .dts rather than in the shared DTSI, which six
other boards include and whose fan wiring has not been checked. Cost:
hwmon fan1_input stops reporting RPM, as on the Odin 3.

Found and measured by jesherman in armada-os/armada-packages#23. The EVO
stays outside the device gate; this removes one of the two reasons it is
there.
xiaodoudou pushed a commit to xiaodoudou/distribution that referenced this pull request Aug 27, 2026
qcs8550-ayaneo-pocket-common.dtsi gives pwm-fan an edge-falling TLMM 64
interrupt for the tachometer. Measured on a Pocket EVO it fires about 80
times a second whenever the fan spins and repeatedly pulls the SoC back
out of deep suspend, with /proc/interrupts climbing past 230,000; with
the fan stopped the same suspend holds. The AYN Odin 3 declares no tacho
interrupt and suspends for hours.

Overridden in the EVO .dts rather than in the shared DTSI, which six
other boards include and whose fan wiring has not been checked. Cost:
hwmon fan1_input stops reporting RPM, as on the Odin 3.

Found and measured by jesherman in armada-os/armada-packages#23. The EVO
stays outside the device gate; this removes one of the two reasons it is
there.
xiaodoudou pushed a commit to xiaodoudou/distribution that referenced this pull request Aug 27, 2026
qcs8550-ayaneo-pocket-common.dtsi gives pwm-fan an edge-falling TLMM 64
interrupt for the tachometer. Measured on a Pocket EVO it fires about 80
times a second whenever the fan spins and repeatedly pulls the SoC back
out of deep suspend, with /proc/interrupts climbing past 230,000; with
the fan stopped the same suspend holds. The AYN Odin 3 declares no tacho
interrupt and suspends for hours.

Overridden in the EVO .dts rather than in the shared DTSI, which six
other boards include and whose fan wiring has not been checked. Cost:
hwmon fan1_input stops reporting RPM, as on the Odin 3.

Found and measured by jesherman in armada-os/armada-packages#23. The EVO
stays outside the device gate; this removes one of the two reasons it is
there.
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.

2 participants