Symptom: pressing shutdown left the phone hung on a black screen with the last console text, never powering off, needing a hard reset. Reboot worked fine. First we fixed the hang (clean power-cut), but the phone still auto-rebooted after ~15-25 seconds even on battery. That re-power was the main PMIC's own watchdog (WTSR), and it is now fixed: the phone shuts down and stays off from any shutdown path. See "The fix (implemented and verified)" below.
The kernel's pm_power_off is PSCI SYSTEM_OFF. On this device S-Boot's secure firmware
hangs on SYSTEM_OFF instead of cutting power (reboot works because it uses a
different PSCI path, SYSTEM_RESET). So the kernel called into EL3 and never came back.
Power is cut by driving the PS_HOLD pin low, which tells the main PMIC (S2MPS19) to
drop the rails. On this SoC (downstream exynos-reboot.c, CONFIG_SOC_EXYNOS9830) that
is PMU register PS_HOLD_CONTROL = 0x030C, clearing bit 8 (PS_HOLD_EN):
regmap_update_bits(pmu, 0x030C, 0x100, 0). Note it is 0x030C, not the old S5P value
0x330C (using 0x330C reproduces the original hang). The same #else branch also gives
SWRESET = 0x3A00, which matches the working reboot node, confirming the branch.
The PMU syscon maps at physical 0x15860000 (the DT node is named @11860000 but its
reg overrides to 0x15860000).
- A
syscon-poweroffDT node on the PMU (offset = 0x030c,mask = 0x100,value = 0x0) andCONFIG_POWER_RESET_SYSCON_POWEROFF=y, registered atSYS_OFF_PRIO_HIGHso it runs before the broken PSCI handler. - An ACPM "enter WFI / STOP" step before PS_HOLD, mirroring the vendor's
exynos_acpm_reboot()->acpm_enter_wfi(): an ACPM IPC withcmd[0] = 1 << 22(ACPM_IPC_PROTOCOL_STOP) on the ACPM framework channel (firmware channel id 4, found by logging the channel table; index == id on this firmware). Added to the in-tree ACPM driver and registered as a power-off handler atSYS_OFF_PRIO_FIRMWARE.
Shutdown became a clean systemd power-off and PS_HOLD 0x030C really does cut power (the
screen goes black; the behaviour changed from a permanent hang to a clean power-cut). But
the phone auto-reboots ~20 s later, even unplugged. The ACPM STOP does not suppress it.
The re-power is not the APM and not the power button. Proof: triggering
systemctl poweroff over SSH with nothing touched still re-powers at ~20 s. The cause is the
main PMIC (S2MPS19) WTSR (Watchdog Timer Software Reset, RTC register 0x01 bit 6) and
SMPL (bit 7). S-Boot leaves them enabled. On a normal Samsung phone the PMIC's RTC
driver disables them during shutdown (s2m_rtc_shutdown -> clear WTSR/SMPL in RTC reg
0x01). But mainline rtc-s5m.c has no such shutdown disable, and on this port no PMIC or
RTC driver is loaded at all (/sys/class/rtc is empty) because the S2MPS19 is managed
entirely over ACPM. So nothing ever disables WTSR, its watchdog times out ~20 s after
PS_HOLD drops, and it power-cycles the phone.
exynos_acpm_force_apm_wdt_reset (STOP_WDT, bit 27) does the opposite (forces a reset), so
it is not the fix.
Clear WTSR (bit 6) and SMPL (bit 7) in the PMIC's RTC register 0x01, over ACPM, before
dropping PS_HOLD. Addressing: ACPM IPC channel 2 (PMIC), speedy channel 0, S2MPS19
RTC sub-address 0x02, register 0x01, read-modify-write to clear bits 6 and 7.
Validation (before touching the poweroff path): a read-only one-shot module
(acpm-rtc-probe.c) dumped the RTC block over ACPM using the in-tree
handle->ops->pmic.bulk_read. RTC reg 0x01 read back 0xe3, WTSR_EN and SMPL_EN both
armed, exactly as diagnosed. The same register via the PMIC sub-address (0x01) returned
0x10, proving the ACPM type field is the S2MPS19 sub-block i2c address (PMIC 0x01,
RTC 0x02, DEBUG 0x0F). SUB_SMPL (CAPSEL reg 0x03 bit 3) already read 0, matching the
vendor shutdown sequence which clears it too.
Implementation: s2mps19_disable_wtsr_smpl() in exynos-acpm.c, called at the top of
acpm_power_off_notify() BEFORE acpm_enter_wfi() sends the APM STOP, because the APM
must still be alive to service the PMIC channel. Read reg 0x01, write it back with bits
6/7 cleared if set, read back and log with dev_emerg. The full patched driver is
kernel/drivers/acpm-pmic/exynos-acpm.c in this repo.
Result: flashed as kernel #22 and tested on battery over SSH: systemctl poweroff,
screen black, phone stays off. Because the handler sits in the kernel sys-off chain,
every userspace shutdown path (systemctl poweroff, the Plasma GUI shutdown, poweroff,
halt -p) gets the fix automatically; there is nothing per-app to configure. Power back
on with the power button. Note that plugging in USB power while off can boot the phone via
charger detection; that is normal PMIC behaviour, not the WTSR bug. The shutdown-time
dev_emerg lines are usually lost from the journal because PS_HOLD cuts power before
journald flushes, so the staying-off behaviour is the proof of record.