diff --git a/repos/libports/run/acpi_suspend.run b/repos/libports/run/acpi_suspend.run
new file mode 100644
index 0000000000..d564adf64b
--- /dev/null
+++ b/repos/libports/run/acpi_suspend.run
@@ -0,0 +1,381 @@
+#
+# Test to trigger periodically ACPI suspend and resume and periodically
+# trying to restart graphic driver.
+#
+# The pc_intel_fb_drv is restarting on X201 successfully after resume.
+# On Qemu the restart of vesa_fb_drv after resume does not work up to now.
+#
+# Intel AMT SOL most the time does not work after resume.
+# PCMCIA Serial card worked reliable on X201 after resume.
+#
+
+assert_spec x86
+assert_spec nova
+
+# non Intel machines has no GPU support, e.g. Qemu and AMD
+set board_non_intel [expr [have_include "power_on/qemu"]]
+
+if {$board_non_intel} {
+ set fb_platform_service "platform_drv"
+} else {
+ set fb_platform_service "intel_gpu_drv"
+}
+
+
+proc display_config { } {
+ global board_non_intel
+
+ if {$board_non_intel} {
+ return {
+
+
+
+
+
+
+
+ }
+ }
+
+ return {
+
+
+
+
+
+
+ }
+}
+
+proc gpu_config { } {
+ global board_non_intel
+
+ if {$board_non_intel} return
+
+ return {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+}
+
+
+set build_components {
+ core timer init
+ server/report_rom
+ server/dynamic_rom
+ server/rom_filter
+ drivers/acpi
+ drivers/platform
+ drivers/framebuffer/intel/pc
+ drivers/framebuffer/vesa
+ drivers/framebuffer/boot
+ drivers/gpu/intel
+ app/acpica
+ app/pci_decode
+ test/framebuffer
+ test/suspend
+}
+
+build $build_components
+
+create_boot_directory
+
+set config ""
+append config {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ } [gpu_config] {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ } [display_config] {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
+
+install_config $config
+
+# non PCI devices for platform_drv, e.g. ps2/pit
+file copy [select_from_repositories board/[board]/devices] [run_dir]/genode/devices
+
+set boot_modules {
+ core ld.lib.so init timer
+ report_rom dynamic_rom rom_filter
+ acpi_drv pc_platform_drv pci_decode
+ pc_intel_fb_drv test-framebuffer vesa_fb_drv intel_gpu_drv boot_fb_drv
+ acpica
+ test-suspend
+}
+
+build_boot_image $boot_modules
+
+# qemu machine model q35 and multiple CPUs don't work with NOVA kernel
+#
+# src/lapic.cpp Acpi::delay(2) spins on PM_TMR forever
+#
+# According to qemu monitor "info mtree",
+#
+# address-space: I/O
+# 0000000000000000-000000000000ffff (prio 0, i/o): io
+# ...
+# 0000000000000600-000000000000067f (prio 0, i/o): ich9-pm
+# 0000000000000600-0000000000000603 (prio 0, i/o): acpi-evt
+# 0000000000000604-0000000000000605 (prio 0, i/o): acpi-cnt
+# 0000000000000608-000000000000060b (prio 0, i/o): acpi-tmr
+# 0000000000000620-000000000000062f (prio 0, i/o): acpi-gpe0
+# 0000000000000630-0000000000000637 (prio 0, i/o): acpi-smi
+# 0000000000000660-000000000000067f (prio 0, i/o): sm-tco
+#
+# address-space: I/O
+# 0000000000000000-000000000000ffff (prio 0, i/o): io
+# 0000000000000000-0000000000000003 (prio 0, i/o): acpi-evt
+# 0000000000000004-0000000000000005 (prio 0, i/o): acpi-cnt
+# 0000000000000008-000000000000000b (prio 0, i/o): acpi-tmr
+# 0000000000000020-000000000000002f (prio 0, i/o): acpi-gpe0
+# 0000000000000030-0000000000000037 (prio 0, i/o): acpi-smi
+# 0000000000000060-000000000000007f (prio 0, i/o): sm-tco
+#
+# the "ich9-pm" device behind/attached on a LPC PCI device
+#
+# ./hw/isa/lpc_ich9.c
+# ./hw/acpi/ich9.c: memory_region_init(&pm->io, OBJECT(lpc_pci), "ich9-pm", ICH9_PMIO_SIZE)
+#
+# is not at the right i/o space right location anymore. It seems that the
+# parent of ich9-pm stays disabled ...
+#
+# Further debugging shows:
+#
+# qemu/roms/seabios/src/resume.c s3_resume -> pci_resume
+# qemu/roms/seabios/src/fw/pciinit.c pci_resume
+#
+# In pci_resume the mmcfg and q35 and ich9-pm for PCIe is tried to be
+# re-enabled, but actually the calls never hit in Qemu.
+# It seems that mch_mmconfig_setup should use I/O PCI access in order to
+# enable MMIO PCI MMCFG access.
+#
+append qemu_args "-smp 1"
+
+run_genode_until forever
diff --git a/repos/libports/src/test/suspend/component.cc b/repos/libports/src/test/suspend/component.cc
new file mode 100644
index 0000000000..6b7b90d5e1
--- /dev/null
+++ b/repos/libports/src/test/suspend/component.cc
@@ -0,0 +1,124 @@
+/*
+ * \brief Test to trigger ACPI S3 suspend via Pd::managing_system()
+ * \author Alexander Boettcher
+ * \date 2022-08-01
+ *
+ */
+
+/*
+ * Copyright (C) 2022 Genode Labs GmbH
+ *
+ * This file is part of the Genode OS framework, which is distributed
+ * under the terms of the GNU Affero General Public License version 3.
+ */
+
+#include
+#include
+#include
+
+
+using namespace Genode;
+
+
+class Suspend
+{
+ private:
+
+ Env &_env;
+ Attached_rom_dataspace _system_rom { _env, "system" };
+ Attached_rom_dataspace _sleep_support { _env, "sleep_states" };
+ Signal_handler _handler { _env.ep(), *this,
+ &Suspend::system_update };
+
+ uint8_t s3_sleep_typea { };
+ uint8_t s3_sleep_typeb { };
+ bool s3_sleep_valid { };
+
+ void suspend()
+ {
+ /*
+ * S0: normal power on
+ * S1: low wake latency sleeping - cpu caches off - no reset vector used on resume in kernel !
+ * S2: low wake latency sleep - start from reset vector
+ * S3: low wake latency sleep - some parts powered off -> "suspend to RAM"
+ * S4: long wake latency sleep - "suspend to disk"
+ * S5: soft off state
+ */
+
+ if (!s3_sleep_valid) {
+ warning("suspend ... denied");
+ return;
+ }
+
+ log("suspend S3 (", s3_sleep_typea, ",", s3_sleep_typeb, ") ...");
+
+ Pd_session::Managing_system_state in, out;
+
+ in.trapno = Pd_session::Managing_system_state::ACPI_SUSPEND_REQUEST;
+ in.ip = s3_sleep_typea;
+ in.sp = s3_sleep_typeb;
+
+ out = _env.pd().managing_system (in);
+
+ if (!out.trapno)
+ log("suspend failed");
+ else
+ log("resumed from S3");
+ }
+
+ void system_update()
+ {
+ _system_rom.update();
+ _sleep_support.update();
+
+ if (_system_rom.valid()) {
+ auto state = _system_rom.xml().attribute_value("state",
+ String<16>(""));
+
+ log("system update requested to '", state, "'");
+
+ if (state == "suspend")
+ suspend();
+ }
+
+ if (_sleep_support.valid()) {
+ _sleep_support.xml().with_optional_sub_node("S3", [&] (auto const &node) {
+ auto const typea = "SLP_TYPa";
+ auto const typeb = "SLP_TYPb";
+
+ s3_sleep_valid = node.attribute_value("supported", false) &&
+ node.has_attribute(typea) &&
+ node.has_attribute(typeb);
+
+ if (s3_sleep_valid) {
+ unsigned tmpa = node.attribute_value(typea, 0u);
+ unsigned tmpb = node.attribute_value(typeb, 0u);
+ if (tmpa < 256)
+ s3_sleep_typea = uint8_t(node.attribute_value(typea, 0u));
+ else
+ s3_sleep_valid = false;
+
+ if (tmpb < 256)
+ s3_sleep_typeb = uint8_t(node.attribute_value(typeb, 0u));
+ else
+ s3_sleep_valid = false;
+ }
+ });
+ }
+ }
+
+ public:
+
+ Suspend(Env &env) : _env(env)
+ {
+ _system_rom.sigh(_handler);
+ _sleep_support.sigh(_handler);
+
+ system_update();
+ }
+};
+
+void Component::construct(Genode::Env &env)
+{
+ static Suspend suspend(env);
+}
diff --git a/repos/libports/src/test/suspend/target.mk b/repos/libports/src/test/suspend/target.mk
new file mode 100644
index 0000000000..b8548910ae
--- /dev/null
+++ b/repos/libports/src/test/suspend/target.mk
@@ -0,0 +1,5 @@
+TARGET = test-suspend
+SRC_CC = component.cc
+LIBS = base
+
+REQUIRES := x86