Hah - wow, and just after I wrote that I managed to make it suspend correctly. This was during the same session, without having rebooted inbetween. This time the messages are:
[34137.910376] Freezing user space processes
[34137.917759] Freezing user space processes completed (elapsed 0.007 seconds)
[34137.917768] OOM killer disabled.
[34137.917771] Freezing remaining freezable tasks
[34137.919068] Freezing remaining freezable tasks completed (elapsed 0.001 seconds)
[34137.919072] printk: Suspending console(s) (use no_console_suspend to debug)
[34138.489532] ACPI: EC: interrupt blocked
[36379.313944] ACPI: EC: interrupt unblocked
[36379.507573] nvme nvme0: 16/0/0 default/read/poll queues
And in particular, the last message before suspend was the “ACPI: EC: interrupt blocked”, and much later (by timestamps) the “ACPI: EC: interrupt unblocked” with no complaint about not reaching deepest state inbetween.
This does suggest that’s where the problem lies, though doesn’t point at what might fix it.