diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-08-17 15:20:57 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-08-17 15:20:57 +0200 |
| commit | 824cc5a96f8a6f666a5c963897c8ab9076b48373 (patch) | |
| tree | 3c0f28e79702487f4ebcc12cf5d94bc3ef751887 /kernel/kapi/devices/power.cpp | |
| parent | 44f28c5ceafafd88b68de6fe2c05fac332ff3c33 (diff) | |
| download | kernel-824cc5a96f8a6f666a5c963897c8ab9076b48373.tar.xz kernel-824cc5a96f8a6f666a5c963897c8ab9076b48373.zip | |
kapi: add power management support to drivers
Diffstat (limited to 'kernel/kapi/devices/power.cpp')
| -rw-r--r-- | kernel/kapi/devices/power.cpp | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/kernel/kapi/devices/power.cpp b/kernel/kapi/devices/power.cpp new file mode 100644 index 00000000..3bc66848 --- /dev/null +++ b/kernel/kapi/devices/power.cpp @@ -0,0 +1,93 @@ +#include <kapi/devices/power.hpp> + +#include <kapi/devices.hpp> + +#include <kstd/memory.hpp> +#include <kstd/print.hpp> +#include <kstd/result.hpp> +#include <kstd/vector.hpp> + +#include <ranges> + +namespace kapi::devices +{ + + namespace + { + auto resume_subtree(device & node) -> void; + + // NOLINTNEXTLINE(misc-no-recursion) + auto suspend_subtree(device & node) -> kstd::result<void> + { + auto suspended_children = kstd::vector<kstd::shared_ptr<device>>{}; + + if (auto as_bus = node.facet<bus>()) + { + for (auto const & child : as_bus->children()) + { + auto result = suspend_subtree(*child); + if (!result) + { + for (auto const & already_suspended : std::views::reverse(suspended_children)) + { + resume_subtree(*already_suspended); + } + + return result; + } + + suspended_children.push_back(child); + } + } + + if (auto driver = node.bound_driver()) + { + auto result = driver->suspend(node); + if (!result) + { + for (auto const & already_suspended : std::views::reverse(suspended_children)) + { + resume_subtree(*already_suspended); + } + + return result; + } + } + + return kstd::success(); + } + + // NOLINTNEXTLINE(misc-no-recursion) + auto resume_subtree(device & node) -> void + { + if (auto driver = node.bound_driver()) + { + auto result = driver->resume(node); + if (!result) + { + kstd::println(kstd::print_sink::stderr, "[OS:PM] failed to resume device '{}': {}", node.name(), + result.error().message()); + } + } + + if (auto as_bus = node.facet<bus>()) + { + for (auto const & child : as_bus->children()) + { + resume_subtree(*child); + } + } + } + } // namespace + + auto suspend_tree(bus & root) -> kstd::result<void> + { + return suspend_subtree(root); + } + + auto resume_tree(bus & root) -> void + { + resume_subtree(root); + } + +} // namespace kapi::devices
\ No newline at end of file |
