Add Resume task

Change-Id: Ibdceed64189c85ded6b160997ff8309db2537c5f
diff --git a/garnet/tests/system_updater/src/lib.rs b/garnet/tests/system_updater/src/lib.rs
index 4db5028..c99b140 100644
--- a/garnet/tests/system_updater/src/lib.rs
+++ b/garnet/tests/system_updater/src/lib.rs
@@ -349,11 +349,17 @@
         mut stream: fidl_fuchsia_device_manager::AdministratorRequestStream,
     ) -> Result<(), Error> {
         while let Some(event) = stream.try_next().await? {
-            let fidl_fuchsia_device_manager::AdministratorRequest::Suspend { flags, responder } =
-                event;
-            eprintln!("TEST: Got reboot request with flags {:?}", flags);
-            *self.called.lock() += 1;
-            responder.send(Status::OK.into_raw())?;
+            match event {
+                fidl_fuchsia_device_manager::AdministratorRequest::Suspend { flags, responder } => {
+                    eprintln!("TEST: Got reboot request with flags {:?}", flags);
+                    *self.called.lock() += 1;
+                    responder.send(Status::OK.into_raw())?;
+                }
+                fidl_fuchsia_device_manager::AdministratorRequest::Resume { state, responder } => {
+                     eprintln!("TEST: Got Resume request with state {:?}", state);
+                     responder.send(Status::OK.into_raw())?;
+                }
+            }
         }
 
         Ok(())
diff --git a/src/devices/coordinator/BUILD.gn b/src/devices/coordinator/BUILD.gn
index 864f141..cc48108 100644
--- a/src/devices/coordinator/BUILD.gn
+++ b/src/devices/coordinator/BUILD.gn
@@ -32,6 +32,7 @@
     "fidl.cc",
     "main.cc",
     "suspend-task.cc",
+    "resume-task.cc",
     "system-instance.cc",
     "system-instance.h",
     "task.cc",
@@ -109,6 +110,7 @@
     "env.cc",
     "fdio.cc",
     "fidl.cc",
+    "resume-task.cc",
     "suspend-task.cc",
     "system-instance.cc",
     "system-instance.h",
diff --git a/src/devices/coordinator/coordinator-test.cc b/src/devices/coordinator/coordinator-test.cc
index 8715371..fd5986e 100644
--- a/src/devices/coordinator/coordinator-test.cc
+++ b/src/devices/coordinator/coordinator-test.cc
@@ -609,6 +609,60 @@
   SendSuspendReply(remote, return_status);
 }
 
+// Reads a Resume request from remote and checks that it is for the expected
+// target state, without sending a response. |SendResumeReply| can be used to send the desired
+// response.
+void CheckResumeReceived(const zx::channel& remote, SystemPowerState target_state) {
+  // Read the Resume request.
+  FIDL_ALIGNDECL uint8_t bytes[ZX_CHANNEL_MAX_MSG_BYTES];
+  zx_handle_t handles[ZX_CHANNEL_MAX_MSG_HANDLES];
+  uint32_t actual_bytes;
+  uint32_t actual_handles;
+  zx_status_t status = remote.read(0, bytes, handles, sizeof(bytes), fbl::count_of(handles),
+                                   &actual_bytes, &actual_handles);
+  ASSERT_OK(status);
+  ASSERT_LT(0, actual_bytes);
+  ASSERT_EQ(0, actual_handles);
+
+  // Validate the Resume request.
+  auto hdr = reinterpret_cast<fidl_message_header_t*>(bytes);
+  ASSERT_EQ(fuchsia_device_manager_DeviceControllerResumeOrdinal, hdr->ordinal);
+  status = fidl_decode(&fuchsia_device_manager_DeviceControllerResumeRequestTable, bytes,
+                       actual_bytes, handles, actual_handles, nullptr);
+  ASSERT_OK(status);
+  auto req = reinterpret_cast<fuchsia_device_manager_DeviceControllerResumeRequest*>(bytes);
+  ASSERT_EQ(static_cast<SystemPowerState>(req->target_system_state), target_state);
+}
+
+// Sends a response with the given return_status. This can be used to reply to a
+// request received by |CheckResumeReceived|.
+void SendResumeReply(const zx::channel& remote, zx_status_t return_status) {
+  FIDL_ALIGNDECL uint8_t bytes[ZX_CHANNEL_MAX_MSG_BYTES];
+  zx_handle_t handles[ZX_CHANNEL_MAX_MSG_HANDLES];
+  uint32_t actual_handles;
+
+  // Write the Resume response.
+  memset(bytes, 0, sizeof(bytes));
+  auto resp = reinterpret_cast<fuchsia_device_manager_DeviceControllerResumeResponse*>(bytes);
+  resp->hdr.ordinal = fuchsia_device_manager_DeviceControllerResumeOrdinal;
+  resp->status = return_status;
+  zx_status_t status =
+      fidl_encode(&fuchsia_device_manager_DeviceControllerResumeResponseTable, bytes, sizeof(*resp),
+                  handles, fbl::count_of(handles), &actual_handles, nullptr);
+  ASSERT_OK(status);
+  ASSERT_EQ(0, actual_handles);
+  status = remote.write(0, bytes, sizeof(*resp), nullptr, 0);
+  ASSERT_OK(status);
+}
+
+// Reads a Resume request from remote, checks that it is for the expected
+// target state, and then sends the given response.
+void CheckResumeReceived(const zx::channel& remote, SystemPowerState target_state,
+                         zx_status_t return_status) {
+  CheckResumeReceived(remote, target_state);
+  SendResumeReply(remote, return_status);
+}
+
 // Reads a CreateCompositeDevice from remote, checks expectations, and sends
 // a ZX_OK response.
 void CheckCreateCompositeDeviceReceived(const zx::channel& remote, const char* expected_name,
@@ -707,9 +761,7 @@
 
   async::Loop* coordinator_loop() { return &coordinator_loop_; }
   bool coordinator_loop_thread_running() { return coordinator_loop_thread_running_; }
-  void set_coordinator_loop_thread_running(bool value) {
-    coordinator_loop_thread_running_ = value;
-  }
+  void set_coordinator_loop_thread_running(bool value) { coordinator_loop_thread_running_ = value; }
   devmgr::Coordinator* coordinator() { return &coordinator_; }
 
   devmgr::Devhost* devhost() { return &devhost_; }
@@ -729,6 +781,9 @@
   void DoSuspend(uint32_t flags);
   void DoSuspend(uint32_t flags, fit::function<void(uint32_t)> suspend_cb);
 
+  void DoResume(SystemPowerState target_state);
+  void DoResume(SystemPowerState target_state, fit::function<void(SystemPowerState)> resume_cb);
+
   void CheckUnbindReceived(const zx::channel& remote);
   void SendUnbindReply(const zx::channel& remote);
   void CheckUnbindReceivedAndReply(const zx::channel& remote);
@@ -897,6 +952,19 @@
   DoSuspend(flags, [this](uint32_t flags) { coordinator()->Suspend(flags); });
 }
 
+void MultipleDeviceTestCase::DoResume(
+    SystemPowerState target_state, fit::function<void(SystemPowerState target_state)> resume_cb) {
+  resume_cb(target_state);
+  if (!coordinator_loop_thread_running()) {
+    coordinator_loop()->RunUntilIdle();
+  }
+}
+
+void MultipleDeviceTestCase::DoResume(SystemPowerState target_state) {
+  DoResume(target_state,
+           [this](SystemPowerState target_state) { coordinator()->Resume(target_state); });
+}
+
 TEST_F(MultipleDeviceTestCase, RemoveDeadDevice) {
   size_t index;
   ASSERT_NO_FATAL_FAILURES(AddDevice(platform_bus(), "device", 0 /* protocol id */, "", &index));
@@ -954,8 +1022,8 @@
 
   // Verify the UnbindDone response.
   uint32_t actual_bytes;
-  status = remote.read(0, bytes, handles, sizeof(bytes), fbl::count_of(handles),
-                       &actual_bytes, &actual_handles);
+  status = remote.read(0, bytes, handles, sizeof(bytes), fbl::count_of(handles), &actual_bytes,
+                       &actual_handles);
   ASSERT_OK(status);
   ASSERT_LT(0, actual_bytes);
   ASSERT_EQ(0, actual_handles);
@@ -1021,8 +1089,8 @@
 
   // Verify the RemoveDone response.
   uint32_t actual_bytes;
-  status = remote.read(0, bytes, handles, sizeof(bytes), fbl::count_of(handles),
-                       &actual_bytes, &actual_handles);
+  status = remote.read(0, bytes, handles, sizeof(bytes), fbl::count_of(handles), &actual_bytes,
+                       &actual_handles);
   ASSERT_OK(status);
   ASSERT_LT(0, actual_bytes);
   ASSERT_EQ(0, actual_handles);
@@ -1536,13 +1604,13 @@
 
   auto* child_device = device(child_index);
 
-  ASSERT_NO_FATAL_FAILURES(coordinator_.ScheduleDevhostRequestedRemove(parent_device->device,
-                                                                       false /* do_unbind */));
+  ASSERT_NO_FATAL_FAILURES(
+      coordinator_.ScheduleDevhostRequestedRemove(parent_device->device, false /* do_unbind */));
   coordinator_loop()->RunUntilIdle();
 
   // At the same time, have the child try to remove itself.
-  ASSERT_NO_FATAL_FAILURES(coordinator_.ScheduleDevhostRequestedRemove(child_device->device,
-                                                                       false /* do_unbind */));
+  ASSERT_NO_FATAL_FAILURES(
+      coordinator_.ScheduleDevhostRequestedRemove(child_device->device, false /* do_unbind */));
   coordinator_loop()->RunUntilIdle();
 
   // The child device will not reply, as it already called device_remove previously.
@@ -1678,6 +1746,51 @@
   ASSERT_EQ(device(index)->device->state(), want_device_state);
 }
 
+class ResumeTestCase : public MultipleDeviceTestCase {
+ public:
+  void ResumeTest(SystemPowerState target_state);
+  void StateTest(zx_status_t resume_status, devmgr::Device::State want_device_state);
+};
+
+// Verify the resume order is correct
+void ResumeTestCase::ResumeTest(SystemPowerState target_state) {
+  struct DeviceDesc {
+    // Index into the device desc array below.  UINT32_MAX = platform_bus()
+    const size_t parent_desc_index;
+    const char* const name;
+    // index for use with device()
+    size_t index = 0;
+  };
+  DeviceDesc devices[] = {
+      {UINT32_MAX, "root_child1"}, {UINT32_MAX, "root_child2"}, {0, "root_child1_1"},
+      {0, "root_child1_2"},        {2, "root_child1_1_1"},      {1, "root_child2_1"},
+  };
+  for (auto& desc : devices) {
+    fbl::RefPtr<devmgr::Device> parent;
+    if (desc.parent_desc_index == UINT32_MAX) {
+      parent = platform_bus();
+    } else {
+      size_t index = devices[desc.parent_desc_index].index;
+      parent = device(index)->device;
+    }
+    ASSERT_NO_FATAL_FAILURES(AddDevice(parent, desc.name, 0 /* protocol id */, "", &desc.index));
+  }
+
+  ASSERT_NO_FATAL_FAILURES(DoResume(target_state));
+
+  // size_t num_to_resume = fbl::count_of(devices);
+  // while (num_to_resume > 0) {
+  // Check that platform bus received the resume first
+  ASSERT_TRUE(DeviceHasPendingMessages(platform_bus_remote()));
+  coordinator_loop()->RunUntilIdle();
+  ASSERT_NO_FATAL_FAILURES(CheckResumeReceived(platform_bus_remote(), target_state, ZX_OK));
+  //}
+}
+
+TEST_F(ResumeTestCase, FullyOnCheckOrder) {
+  ASSERT_NO_FATAL_FAILURES(ResumeTest(SystemPowerState::SYSTEM_POWER_STATE_FULLY_ON));
+}
+
 class CompositeTestCase : public MultipleDeviceTestCase {
  public:
   ~CompositeTestCase() override = default;
diff --git a/src/devices/coordinator/coordinator.cc b/src/devices/coordinator/coordinator.cc
index 76331ff..94a5a19 100644
--- a/src/devices/coordinator/coordinator.cc
+++ b/src/devices/coordinator/coordinator.cc
@@ -36,14 +36,15 @@
 #include <zircon/syscalls/policy.h>
 #include <zircon/syscalls/system.h>
 
+#include <cstdint>
 #include <utility>
 
 #include <ddk/driver.h>
 #include <driver-info/driver-info.h>
 #include <fbl/auto_call.h>
 #include <fbl/unique_ptr.h>
-#include <libzbi/zbi-cpp.h>
 #include <inspector/inspector.h>
+#include <libzbi/zbi-cpp.h>
 
 #include "composite-device.h"
 #include "devfs.h"
@@ -1175,8 +1176,7 @@
     }
     zx::unowned_process process = task.device().host()->proc();
     char process_name[ZX_MAX_NAME_LEN];
-    zx_status_t status = process->get_property(ZX_PROP_NAME, process_name,
-                                                sizeof(process_name));
+    zx_status_t status = process->get_property(ZX_PROP_NAME, process_name, sizeof(process_name));
     if (status != ZX_OK) {
       strlcpy(process_name, "unknown", sizeof(process_name));
     }
@@ -1233,32 +1233,68 @@
   auto task = SuspendTask::Create(sys_device(), ctx.sflags(), std::move(completion));
   suspend_context().set_task(std::move(task));
 
-  auto status = async::PostDelayedTask(
-      dispatcher(),
-      [this, callback] {
-        if (!InSuspend()) {
-          return;  // Suspend failed to complete.
-        }
-        auto& ctx = suspend_context();
-        log(ERROR, "devcoordinator: DEVICE SUSPEND TIMED OUT\n");
-        log(ERROR, "  sflags: 0x%08x\n", ctx.sflags());
-        dump_suspend_task_dependencies(ctx.task());
-        if (suspend_fallback()) {
-          ::suspend_fallback(root_resource(), ctx.sflags());
-          // Unless in test env, we should not reach here.
-          callback(ZX_ERR_TIMED_OUT);
-        }
-      },
-      zx::sec(30));
+  auto status = async::PostDelayedTask(dispatcher(),
+                                       [this, callback] {
+                                         if (!InSuspend()) {
+                                           return;  // Suspend failed to complete.
+                                         }
+                                         auto& ctx = suspend_context();
+                                         log(ERROR, "devcoordinator: DEVICE SUSPEND TIMED OUT\n");
+                                         log(ERROR, "  sflags: 0x%08x\n", ctx.sflags());
+                                         dump_suspend_task_dependencies(ctx.task());
+                                         if (suspend_fallback()) {
+                                           ::suspend_fallback(root_resource(), ctx.sflags());
+                                           // Unless in test env, we should not reach here.
+                                           callback(ZX_ERR_TIMED_OUT);
+                                         }
+                                       },
+                                       zx::sec(30));
   if (status != ZX_OK) {
     log(ERROR, "devcoordinator: Failed to create suspend timeout watchdog\n");
   }
 }
 
+void Coordinator::Resume(ResumeContext ctx, std::function<void(zx_status_t)> callback) {
+  // The sys device should have a proxy. If not, the system hasn't fully initialized yet and
+  // cannot go to suspend.
+  if (!sys_device_->proxy()) {
+    return;
+  }
+  if (InSuspend()) {
+    return;
+  }
+
+  resume_context() = std::move(ctx);
+
+  auto completion = [this, callback](zx_status_t status) {
+    auto& ctx = resume_context();
+    if (status != ZX_OK) {
+      // do not continue to resume as this indicates a driver resume
+      // problem and should show as a bug
+      log(ERROR, "devcoordinator: failed to resume: %s\n", zx_status_get_string(status));
+      ctx.set_flags(devmgr::ResumeContext::Flags::kSuspended);
+      callback(status);
+      return;
+    }
+    callback(status);
+  };
+
+  printf("MINE MINE Reached Resume: Hippity Hoppity mood\n");
+  // We don't need to resume anything except sys_device and it's children,
+  // since we do not run suspend hooks for children of test or misc
+  auto task = ResumeTask::Create(sys_device(), static_cast<uint32_t>(ctx.target_state()),
+                                 std::move(completion));
+  resume_context().set_task(std::move(task));
+}
+
 void Coordinator::Suspend(uint32_t flags) {
   Suspend(SuspendContext(SuspendContext::Flags::kSuspend, flags), [](zx_status_t) {});
 }
 
+void Coordinator::Resume(SystemPowerState target_state) {
+  Resume(ResumeContext(ResumeContext::Flags::kResume, target_state), [](zx_status_t) {});
+}
+
 fbl::unique_ptr<Driver> Coordinator::ValidateDriver(fbl::unique_ptr<Driver> drv) {
   if ((drv->flags & ZIRCON_DRIVER_NOTE_FLAG_ASAN) && !config_.asan_drivers) {
     if (launched_first_devhost_) {
@@ -1544,6 +1580,20 @@
                   });
               return ZX_ERR_ASYNC;
             },
+        .Resume =
+            [](void* ctx, fuchsia_device_manager_SystemPowerState target_state, fidl_txn_t* txn) {
+              auto* async_txn = fidl_async_txn_create(txn);
+              static_cast<Coordinator*>(ctx)->Resume(
+                  ResumeContext(
+                      ResumeContext::Flags::kResume,
+                      static_cast<llcpp::fuchsia::device::manager::SystemPowerState>(target_state)),
+                  [async_txn](zx_status_t status) {
+                    fuchsia_device_manager_AdministratorResume_reply(
+                        fidl_async_txn_borrow(async_txn), status);
+                    fidl_async_txn_complete(async_txn, true);
+                  });
+              return ZX_ERR_ASYNC;
+            },
     };
 
     const auto status =
@@ -1554,7 +1604,7 @@
       printf("Failed to bind to client channel: %d \n", status);
     }
     return status;
-  };
+  };  // namespace devmgr
   svc_dir->AddEntry(fuchsia_device_manager_Administrator_Name,
                     fbl::MakeRefCounted<fs::Service>(admin));
 
@@ -1594,7 +1644,7 @@
   };
   svc_dir->AddEntry(fuchsia_device_manager_DebugDumper_Name,
                     fbl::MakeRefCounted<fs::Service>(debug));
-}
+}  // namespace devmgr
 
 void Coordinator::OnOOMEvent(async_dispatcher_t* dispatcher, async::WaitBase* wait,
                              zx_status_t status, const zx_packet_signal_t* signal) {
diff --git a/src/devices/coordinator/coordinator.h b/src/devices/coordinator/coordinator.h
index d7a7435..f8f0eeb 100644
--- a/src/devices/coordinator/coordinator.h
+++ b/src/devices/coordinator/coordinator.h
@@ -27,11 +27,15 @@
 #include "devhost.h"
 #include "device.h"
 #include "driver.h"
+#include "fuchsia/device/manager/llcpp/fidl.h"
 #include "metadata.h"
+#include "resume-task.h"
 #include "suspend-task.h"
 #include "unbind-task.h"
 #include "vmo-writer.h"
 
+using llcpp::fuchsia::device::manager::SystemPowerState;
+
 namespace devmgr {
 
 class DevhostLoaderService;
@@ -70,6 +74,36 @@
   uint32_t sflags_ = 0u;
 };
 
+class ResumeContext {
+ public:
+  enum class Flags : uint32_t {
+    kResume = 0u,
+    kSuspended = 1u,
+  };
+  ResumeContext() = default;
+
+  ResumeContext(Flags flags, SystemPowerState resume_state)
+      : target_state_(resume_state), flags_(flags) {}
+
+  ~ResumeContext() {}
+
+  ResumeContext(ResumeContext&&) = default;
+  ResumeContext& operator=(ResumeContext&&) = default;
+
+  Flags flags() const { return flags_; }
+  void set_flags(Flags flags) { flags_ = flags; }
+  void set_task(fbl::RefPtr<ResumeTask> task) { task_ = std::move(task); }
+
+  const ResumeTask& task() const { return *task_; }
+
+  SystemPowerState target_state() const { return target_state_; }
+
+ private:
+  fbl::RefPtr<ResumeTask> task_;
+  SystemPowerState target_state_;
+  Flags flags_ = Flags::kSuspended;
+};
+
 // Values parsed out of argv.  All paths described below are absolute paths.
 struct DevmgrArgs {
   // Load drivers from these directories.  If this is empty, the default will
@@ -232,10 +266,14 @@
   const fbl::RefPtr<Device>& test_device() { return test_device_; }
 
   void Suspend(uint32_t flags);
+  void Resume(SystemPowerState target_state);
 
   SuspendContext& suspend_context() { return suspend_context_; }
   const SuspendContext& suspend_context() const { return suspend_context_; }
 
+  ResumeContext& resume_context() { return resume_context_; }
+  const ResumeContext& resume_context() const { return resume_context_; }
+
   zx_status_t BindFidlServiceProxy(zx::channel listen_on);
 
   zx_status_t BindOutgoingServices(zx::channel listen_on);
@@ -282,6 +320,7 @@
   fbl::RefPtr<Device> test_device_;
 
   SuspendContext suspend_context_;
+  ResumeContext resume_context_;
 
   void OnOOMEvent(async_dispatcher_t* dispatcher, async::WaitBase* wait, zx_status_t status,
                   const zx_packet_signal_t* signal);
@@ -300,6 +339,7 @@
 
   void BuildSuspendList();
   void Suspend(SuspendContext ctx, std::function<void(zx_status_t)> callback);
+  void Resume(ResumeContext ctx, std::function<void(zx_status_t)> callback);
 
   fbl::unique_ptr<Driver> ValidateDriver(fbl::unique_ptr<Driver> drv);
 
diff --git a/src/devices/coordinator/device.cc b/src/devices/coordinator/device.cc
index 486603a..49116e5 100644
--- a/src/devices/coordinator/device.cc
+++ b/src/devices/coordinator/device.cc
@@ -17,6 +17,7 @@
 #include "fidl.h"
 #include "fidl_txn.h"
 #include "log.h"
+#include "resume-task.h"
 #include "suspend-task.h"
 
 namespace devmgr {
@@ -221,6 +222,17 @@
   return active_suspend_;
 }
 
+fbl::RefPtr<ResumeTask> Device::RequestResumeTask(uint32_t target_system_state) {
+  if (active_resume_) {
+    // We don't support different types of resumes concurrently, and
+    // shouldn't be able to reach this state.
+    ZX_ASSERT(target_system_state == active_resume_->target_system_state());
+  } else {
+    active_resume_ = ResumeTask::Create(fbl::RefPtr(this), target_system_state);
+  }
+  return active_resume_;
+}
+
 zx_status_t Device::SendSuspend(uint32_t flags, SuspendCompletion completion) {
   if (suspend_completion_) {
     // We already have a pending suspend
@@ -236,6 +248,21 @@
   return ZX_OK;
 }
 
+zx_status_t Device::SendResume(uint32_t target_system_state, ResumeCompletion completion) {
+  if (resume_completion_) {
+    // We already have a pending resume
+    return ZX_ERR_UNAVAILABLE;
+  }
+  log(DEVLC, "devcoordinator: resume dev %p name='%s'\n", this, name_.data());
+  zx_status_t status = dh_send_resume(this, target_system_state);
+  if (status != ZX_OK) {
+    return status;
+  }
+  state_ = Device::State::kResuming;
+  resume_completion_ = std::move(completion);
+  return ZX_OK;
+}
+
 void Device::CompleteSuspend(zx_status_t status) {
   if (status == ZX_OK) {
     // If a device is being removed, any existing suspend task will be forcibly completed,
@@ -253,6 +280,17 @@
   }
 }
 
+void Device::CompleteResume(zx_status_t status) {
+  if (status != ZX_OK) {
+    state_ = Device::State::kSuspended;
+  } else {
+    state_ = Device::State::kResumed;
+  }
+  if (resume_completion_) {
+    resume_completion_(status);
+  }
+}
+
 void Device::CreateUnbindRemoveTasks(UnbindTaskOpts opts) {
   if (state_ == Device::State::kDead) {
     return;
@@ -287,10 +325,10 @@
       }
     }
   } else {
-     // |do_unbind| may not match the stored field in the existing unbind task due to
-     // the current device_remove / unbind model.
-     // For closest compatibility with the current model, we should prioritize
-     // devhost calls to |ScheduleRemove| over our own scheduled unbind tasks for the children.
+    // |do_unbind| may not match the stored field in the existing unbind task due to
+    // the current device_remove / unbind model.
+    // For closest compatibility with the current model, we should prioritize
+    // devhost calls to |ScheduleRemove| over our own scheduled unbind tasks for the children.
     active_unbind_->set_do_unbind(opts.do_unbind);
   }
 }
@@ -595,6 +633,29 @@
     }
     log(DEVLC, "devcoordinator: suspended dev %p name='%s'\n", this, name_.data());
     CompleteSuspend(resp->status);
+  } else if (ordinal == fuchsia_device_manager_DeviceControllerResumeOrdinal ||
+             ordinal == fuchsia_device_manager_DeviceControllerResumeGenOrdinal) {
+    const char* err_msg = nullptr;
+    r = fidl_decode_msg(&fuchsia_device_manager_DeviceControllerResumeResponseTable, &fidl_msg,
+                        &err_msg);
+    if (r != ZX_OK) {
+      log(ERROR, "devcoordinator: rpc: suspend '%s' received malformed reply: %s\n", name_.data(),
+          err_msg);
+      return ZX_ERR_IO;
+    }
+    auto resp =
+        reinterpret_cast<fuchsia_device_manager_DeviceControllerResumeResponse*>(fidl_msg.bytes);
+    if (resp->status != ZX_OK) {
+      log(ERROR, "devcoordinator: rpc: resume '%s' status %d\n", name_.data(), resp->status);
+    }
+
+    if (!resume_completion_) {
+      log(ERROR, "devcoordinator: rpc: unexpected resume reply for '%s' status %d\n", name_.data(),
+          resp->status);
+      return ZX_ERR_IO;
+    }
+    log(INFO, "devcoordinator: resumed dev %p name='%s'\n", this, name_.data());
+    CompleteResume(resp->status);
   } else {
     log(ERROR, "devcoordinator: rpc: dev '%s' received wrong unexpected reply %16lx\n",
         name_.data(), hdr->ordinal);
diff --git a/src/devices/coordinator/device.h b/src/devices/coordinator/device.h
index 4521e7a..e96d5d2 100644
--- a/src/devices/coordinator/device.h
+++ b/src/devices/coordinator/device.h
@@ -34,6 +34,7 @@
 class RemoveTask;
 class SuspendContext;
 class SuspendTask;
+class ResumeTask;
 class UnbindTask;
 struct UnbindTaskOpts;
 
@@ -305,6 +306,11 @@
   // given completion will be invoked.
   zx_status_t SendSuspend(uint32_t flags, SuspendCompletion completion);
 
+  using ResumeCompletion = fit::callback<void(zx_status_t)>;
+  // Issue a Resume request to this device.  When the response comes in, the
+  // given completion will be invoked.
+  zx_status_t SendResume(uint32_t target_system_state, ResumeCompletion completion);
+
   using UnbindCompletion = fit::callback<void(zx_status_t)>;
   using RemoveCompletion = fit::callback<void(zx_status_t)>;
   // Issue an Unbind request to this device, which will run the unbind hook.
@@ -377,11 +383,22 @@
   // Creates a new suspend task if necessary and returns a reference to it.
   // If one is already in-progress, a reference to it is returned instead
   fbl::RefPtr<SuspendTask> RequestSuspendTask(uint32_t suspend_flags);
+
+  fbl::RefPtr<ResumeTask> GetActiveResume() { return active_resume_; }
+
+  // Request Resume task
+  fbl::RefPtr<ResumeTask> RequestResumeTask(uint32_t system_resume_state);
+
   // Run the completion for the outstanding suspend, if any.  This method is
   // only exposed currently because RemoveDevice is on Coordinator instead of
   // Device.
   void CompleteSuspend(zx_status_t status);
 
+  // Run the completion for the outstanding suspend, if any.  This method is
+  // only exposed currently because RemoveDevice is on Coordinator instead of
+  // Device.
+  void CompleteResume(zx_status_t status);
+
   // Creates the unbind and remove tasks for the device if they do not already exist.
   // |opts| is used to configure the unbind task.
   void CreateUnbindRemoveTasks(UnbindTaskOpts opts);
@@ -426,6 +443,8 @@
     kActive,
     kSuspending,  // The devhost is in the process of suspending the device.
     kSuspended,
+    kResuming,   // The devhost is in the process of resuming the device.
+    kResumed,    // Resume is complete.The device marked active, after all children are resumed.
     kUnbinding,  // The devhost is in the process of unbinding and removing the device.
     kDead,       // The device has been remove()'d
   };
@@ -457,6 +476,8 @@
     fbl::AutoLock<fbl::Mutex> lock(&test_state_lock_);
     test_state_ = new_state;
   }
+
+  void clear_active_resume() { active_resume_ = nullptr; }
   void set_test_time(zx::duration& test_time) { test_time_ = test_time; }
   void set_test_reply_required(bool required) { test_reply_required_ = required; }
   zx::duration& test_time() { return test_time_; }
@@ -534,6 +555,12 @@
   // it.
   SuspendCompletion suspend_completion_;
 
+  // If a resume is in-progress, this task represents it.
+  fbl::RefPtr<ResumeTask> active_resume_;
+  // If a Resume is in-progress, this completion will be invoked when it is
+  // completed.
+  ResumeCompletion resume_completion_;
+
   // If an unbind is in-progress, this task represents it.
   fbl::RefPtr<UnbindTask> active_unbind_;
   // If an unbind is in-progress, this completion will be invoked when it is
diff --git a/src/devices/coordinator/fidl.cc b/src/devices/coordinator/fidl.cc
index 24bb967..3ebb830 100644
--- a/src/devices/coordinator/fidl.cc
+++ b/src/devices/coordinator/fidl.cc
@@ -151,6 +151,21 @@
   return msg.Write(dev->channel()->get(), 0);
 }
 
+zx_status_t dh_send_resume(const Device* dev, uint32_t target_system_state) {
+  FIDL_ALIGNDECL char wr_bytes[sizeof(fuchsia_device_manager_DeviceControllerResumeRequest)];
+  fidl::Builder builder(wr_bytes, sizeof(wr_bytes));
+
+  auto req = builder.New<fuchsia_device_manager_DeviceControllerResumeRequest>();
+  ZX_ASSERT(req != nullptr);
+  req->hdr.ordinal = fuchsia_device_manager_DeviceControllerResumeOrdinal;
+  // TODO(teisenbe): Allocate and track txids
+  req->hdr.txid = 1;
+  req->target_system_state = target_system_state;
+
+  fidl::Message msg(builder.Finalize(), fidl::HandlePart(nullptr, 0));
+  return msg.Write(dev->channel()->get(), 0);
+}
+
 zx_status_t dh_send_complete_compatibility_tests(const Device* dev, zx_status_t status) {
   FIDL_ALIGNDECL char
       wr_bytes[sizeof(fuchsia_device_manager_DeviceControllerCompleteCompatibilityTestsRequest)];
diff --git a/src/devices/coordinator/fidl.h b/src/devices/coordinator/fidl.h
index 9f9cccb..a46d1f0 100644
--- a/src/devices/coordinator/fidl.h
+++ b/src/devices/coordinator/fidl.h
@@ -23,6 +23,7 @@
 zx_status_t dh_send_bind_driver(const Device* dev, const char* libname, zx::vmo driver);
 zx_status_t dh_send_connect_proxy(const Device* dev, zx::channel proxy);
 zx_status_t dh_send_suspend(const Device* dev, uint32_t flags);
+zx_status_t dh_send_resume(const Device* dev, uint32_t target_system_state);
 zx_status_t dh_send_unbind(const Device* dev);
 zx_status_t dh_send_complete_removal(const Device* dev);
 zx_status_t dh_send_complete_compatibility_tests(const Device* dev, zx_status_t test_status_);
diff --git a/src/devices/coordinator/resume-task.cc b/src/devices/coordinator/resume-task.cc
new file mode 100644
index 0000000..73abb86
--- /dev/null
+++ b/src/devices/coordinator/resume-task.cc
@@ -0,0 +1,182 @@
+// Copyright 2019 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "resume-task.h"
+
+#include "coordinator.h"
+
+namespace devmgr {
+
+ResumeTask::ResumeTask(fbl::RefPtr<Device> device, uint32_t target_system_state,
+                       Completion completion)
+    : Task(device->coordinator->dispatcher(), std::move(completion)),
+      device_(std::move(device)),
+      target_system_state_(target_system_state) {}
+
+ResumeTask::~ResumeTask() = default;
+
+fbl::RefPtr<ResumeTask> ResumeTask::Create(fbl::RefPtr<Device> device, uint32_t target_system_state,
+                                           Completion completion) {
+  return fbl::MakeRefCounted<ResumeTask>(std::move(device), target_system_state,
+                                         std::move(completion));
+}
+
+bool ResumeTask::AddChildResumeTasks() {
+  bool found_more_dependencies = false;
+  printf("AddChildResumeTasks START for %s\n", device_->name().data());
+  for (auto& child : device_->children()) {
+    // Use a switch statement here so that this gets reconsidered if we add
+    // more states.
+    switch (child.state()) {
+      // If the device is dead, any existing resume task would have been forcibly completed.
+      case Device::State::kDead:
+      case Device::State::kActive:
+        continue;
+      case Device::State::kUnbinding:
+      case Device::State::kSuspending:
+      case Device::State::kResuming:
+      case Device::State::kResumed:
+      case Device::State::kSuspended:
+        printf("Adding resume task for dependency for child: %s\n", child.name().data());
+        AddDependency(child.RequestResumeTask(target_system_state_));
+        found_more_dependencies = true;
+        break;
+    }
+  }
+  printf("AddChildResumeTasks STOP for %s. found_more_deps: %d\n", device_->name().data(),
+         found_more_dependencies);
+  return found_more_dependencies;
+}
+
+void ResumeTask::Run() {
+  switch (device_->state()) {
+    case Device::State::kDead:
+    case Device::State::kActive:
+      return Complete(ZX_OK);
+    case Device::State::kSuspending:
+    case Device::State::kUnbinding:
+    case Device::State::kSuspended:
+    case Device::State::kResumed:
+    case Device::State::kResuming:
+      break;
+  }
+
+  // The device is about to be unbound, wait for it to complete.
+  // Eventually we complete when device goes to DEAD
+  if (device_->state() == Device::State::kUnbinding) {
+    // The remove task depends on the unbind task, so wait for that to complete.
+    auto remove_task = device_->GetActiveRemove();
+    ZX_ASSERT(remove_task != nullptr);
+    AddDependency(remove_task);
+    return;
+  }
+
+  // The device is about to be suspended, wait for it to complete.
+  if (device_->state() == Device::State::kSuspending) {
+    auto suspend_task = device_->GetActiveSuspend();
+    ZX_ASSERT(suspend_task != nullptr);
+    AddDependency(suspend_task);
+    return;
+  }
+
+  auto completion = [this](zx_status_t status) {
+    if (status != ZX_OK) {
+      printf("MINE MINE : ResumeTask:%s :RESUME HOOK FAILED\n", device_->name().data());
+      return Complete(status);
+    }
+    // Handle the device proxy, if it exists, before children since they might
+    // depend on it.
+    if (device_->proxy() != nullptr) {
+      switch (device_->proxy()->state()) {
+        case Device::State::kDead:
+          // Proxy is dead. We cannot resume devices under. Complete with ZX_OK.
+          // We should not consider this error.
+          return Complete(ZX_OK);
+        case Device::State::kActive:
+          break;
+        case Device::State::kSuspending:
+        case Device::State::kUnbinding:
+        case Device::State::kSuspended:
+        case Device::State::kResumed:
+        case Device::State::kResuming:
+          printf("Adding resume task for dependency for device: %s proxy device: %s\n",
+                 device_->name().data(), device_->proxy()->name().data());
+          AddDependency(device_->proxy()->RequestResumeTask(target_system_state_));
+          child_resume_tasks_not_issued_ = true;
+          return;
+      }
+    }
+    child_resume_tasks_not_issued_ = false;
+    if (AddChildResumeTasks()) {
+      return;
+    }
+
+    printf("MINE MINE : ResumeTask:%s :COMPLETE: No more children\n", device_->name().data());
+    device_->set_state(Device::State::kActive);
+    device_->clear_active_resume();
+    return Complete(ZX_OK);
+  };
+
+  if (device_->state() == Device::State::kSuspended) {
+    printf("MINE MINE : ResumeTask: %s: START: devstate: SUSPENDED\n", device_->name().data());
+    if (device_->host() == nullptr) {
+      // pretend this completed successfully.
+      device_->set_state(Device::State::kResumed);
+      printf("MINE MINE : ResumeTask: %s No HOST.\n", device_->name().data());
+      child_resume_tasks_not_issued_ = true;
+      completion(ZX_OK);
+      return;
+    } else {
+      printf("MINE MINE : ResumeTask: %s SENDING RESUME\n", device_->name().data());
+      zx_status_t status = device_->SendResume(target_system_state_, std::move(completion));
+      if (status != ZX_OK) {
+        printf("MINE MINE : ResumeTask:%s COMPLETE: SEND RESUME FAILED\n", device_->name().data());
+        device_->clear_active_resume();
+        return Complete(status);
+      }
+    }
+  }
+
+  // This means this device's resume is complete and we need to handle the children.
+  if (device_->state() == Device::State::kResumed) {
+    // We come back here after proxy resume is complete unless it failed We cannot resume devices
+    // under, unless proxy is active. We should not consider this error, because we do not want
+    // resume task to fail, only because we have a device removed.
+    if (device_->proxy() != nullptr && device_->proxy()->state() != Device::State::kActive) {
+      printf("MINE MINE : ResumeTask:%s proxy state: %d\n", device_->name().data(),
+             device_->proxy()->state());
+      device_->set_state(Device::State::kActive);
+      device_->clear_active_resume();
+      return Complete(ZX_OK);
+    }
+    if (child_resume_tasks_not_issued_) {
+      child_resume_tasks_not_issued_ = false;
+      if (AddChildResumeTasks()) {
+        for (auto* dependency : Dependencies()) {
+          printf("The dependency %s added\n",
+                 reinterpret_cast<const ResumeTask*>(dependency)->device().name().data());
+        }
+        return;
+      }
+      printf("MINE MINE : ResumeTask:%s COMPLETE: ADD CHILDREN FAILED\n", device_->name().data());
+      device_->set_state(Device::State::kActive);
+      device_->clear_active_resume();
+      return Complete(ZX_OK);
+    }
+    // we have completed all dependencies. We should return ZX_OK, because
+    // this device has been resumed, although children are all not resumed.
+    // Complete the ResumeTask.
+    device_->set_state(Device::State::kActive);
+    device_->clear_active_resume();
+    printf("MINE MINE : ResumeTask: Completed all dependencies for %s\n", device_->name().data());
+    for (auto* dependency : Dependencies()) {
+      if (dependency->is_completed()) {
+        printf("The dependency %s complete\n",
+               reinterpret_cast<const ResumeTask*>(dependency)->device().name().data());
+      }
+    }
+    Complete(ZX_OK);
+  }
+}
+}  // namespace devmgr
diff --git a/src/devices/coordinator/resume-task.h b/src/devices/coordinator/resume-task.h
new file mode 100644
index 0000000..42c6455
--- /dev/null
+++ b/src/devices/coordinator/resume-task.h
@@ -0,0 +1,40 @@
+// Copyright 2019 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ZIRCON_SYSTEM_CORE_DEVMGR_DEVCOORDINATOR_RESUME_TASK_H_
+#define ZIRCON_SYSTEM_CORE_DEVMGR_DEVCOORDINATOR_RESUME_TASK_H_
+
+#include "device.h"
+#include "task.h"
+
+namespace devmgr {
+
+class ResumeTask final : public Task {
+ public:
+  static fbl::RefPtr<ResumeTask> Create(fbl::RefPtr<Device> device, uint32_t target_system_state,
+                                         Completion completion = nullptr);
+
+  // Don/t invoke this, use Create
+  ResumeTask(fbl::RefPtr<Device> device, uint32_t target_system_state, Completion completion);
+
+  uint32_t target_system_state() { return target_system_state_; }
+
+  ~ResumeTask() final;
+
+  const Device& device() const { return *device_; }
+
+ private:
+  void Run() final;
+  bool AddChildResumeTasks();
+
+  // The device being resumeed
+  fbl::RefPtr<Device> device_;
+  // Target system resume state
+  uint32_t target_system_state_;
+  bool child_resume_tasks_not_issued_ = false;
+};
+
+}  // namespace devmgr
+
+#endif  // ZIRCON_SYSTEM_CORE_DEVMGR_DEVCOORDINATOR_RESUME_TASK_H_
diff --git a/src/devices/coordinator/suspend-task.cc b/src/devices/coordinator/suspend-task.cc
index bec4c3a3..4800bb2 100644
--- a/src/devices/coordinator/suspend-task.cc
+++ b/src/devices/coordinator/suspend-task.cc
@@ -33,6 +33,8 @@
       case Device::State::kUnbinding:
       case Device::State::kSuspending:
       case Device::State::kActive:
+      case Device::State::kResuming:
+      case Device::State::kResumed:
         break;
     }
 
@@ -49,6 +51,8 @@
     switch (device_->proxy()->state()) {
       case Device::State::kDead:
       case Device::State::kSuspended:
+      case Device::State::kResuming:
+      case Device::State::kResumed:
         break;
       case Device::State::kUnbinding:
       case Device::State::kSuspending:
@@ -68,14 +72,25 @@
     return;
   }
 
+  // The device is about to be resumed, wait for it to complete.
+  if (device_->state() == Device::State::kResuming) {
+    auto resume_task = device_->GetActiveResume();
+    AddDependency(resume_task);
+    return;
+  }
+
   // Check if this device is not in a devhost.  This happens for the
   // top-level devices like /sys provided by devcoordinator,
   // or the device is already dead.
   if (device_->host() == nullptr) {
+    device_->set_state(Device::State::kSuspended);
     return Complete(ZX_OK);
   }
 
-  auto completion = [this](zx_status_t status) { Complete(status); };
+  auto completion = [this](zx_status_t status) {
+    device_->set_state(Device::State::kSuspended);
+    Complete(status);
+  };
   zx_status_t status = device_->SendSuspend(flags_, std::move(completion));
   if (status != ZX_OK) {
     Complete(status);
diff --git a/src/devices/coordinator/unbind-task.cc b/src/devices/coordinator/unbind-task.cc
index 6227cd6..ba0dc2d6 100644
--- a/src/devices/coordinator/unbind-task.cc
+++ b/src/devices/coordinator/unbind-task.cc
@@ -44,6 +44,8 @@
       case Device::State::kSuspended:
       // The created unbind task will wait for the suspend to complete.
       case Device::State::kSuspending:
+      case Device::State::kResuming:
+      case Device::State::kResumed:
       case Device::State::kActive: {
         device_->proxy()->CreateUnbindRemoveTasks(UnbindTaskOpts{
             .do_unbind = false, .post_on_create = false, .devhost_requested = false});
@@ -83,6 +85,8 @@
         continue;
       case Device::State::kSuspended:
       case Device::State::kSuspending:
+      case Device::State::kResuming:
+      case Device::State::kResumed:
       case Device::State::kActive:
         break;
     }
@@ -120,6 +124,13 @@
     return;
   }
 
+  if (device_->state() == Device::State::kResuming) {
+    auto resume_task = device_->GetActiveResume();
+    ZX_ASSERT(resume_task != nullptr);
+    AddDependency(resume_task);
+    return;
+  }
+
   // We need to schedule the child tasks before completing the unbind task runs,
   // as composite device disassociation may occur.
   ScheduleUnbindChildren();
diff --git a/src/modular/tests/sessionmgr_integration_test.cc b/src/modular/tests/sessionmgr_integration_test.cc
index 8f4dda9..b8cda40 100644
--- a/src/modular/tests/sessionmgr_integration_test.cc
+++ b/src/modular/tests/sessionmgr_integration_test.cc
@@ -17,6 +17,7 @@
 class MockAdmin : public fuchsia::device::manager::Administrator {
  public:
   bool suspend_called() { return suspend_called_; }
+  bool resume_called() { return resume_called_; }
 
  private:
   void Suspend(uint32_t flags, SuspendCallback callback) override {
@@ -26,7 +27,15 @@
     callback(ZX_OK);
   }
 
+  void Resume(fuchsia::device::manager::SystemPowerState target_state,
+              ResumeCallback callback) override {
+    ASSERT_FALSE(resume_called_);
+    resume_called_ = true;
+    callback(ZX_OK);
+  }
+
   bool suspend_called_ = false;
+  bool resume_called_ = false;
 };
 
 TEST_F(SessionmgrIntegrationTest, RebootCalledIfSessionmgrCrashNumberReachesRetryLimit) {
diff --git a/src/recovery/factory_reset/factory_reset_unittest.cc b/src/recovery/factory_reset/factory_reset_unittest.cc
index 30cf04b..2cef037 100644
--- a/src/recovery/factory_reset/factory_reset_unittest.cc
+++ b/src/recovery/factory_reset/factory_reset_unittest.cc
@@ -4,10 +4,7 @@
 
 #include "factory_reset.h"
 
-#include <fbl/algorithm.h>
 #include <fcntl.h>
-#include <fs-management/fvm.h>
-#include <fs-management/mount.h>
 #include <fuchsia/device/manager/cpp/fidl.h>
 #include <lib/async-loop/cpp/loop.h>
 #include <lib/async-loop/default.h>
@@ -17,9 +14,13 @@
 #include <lib/fidl/cpp/binding_set.h>
 #include <lib/fzl/fdio.h>
 #include <lib/zx/vmo.h>
-#include <ramdevice-client/ramdisk.h>
 #include <zircon/hw/gpt.h>
 
+#include <fbl/algorithm.h>
+#include <fs-management/fvm.h>
+#include <fs-management/mount.h>
+#include <ramdevice-client/ramdisk.h>
+
 #include "gtest/gtest.h"
 
 namespace {
@@ -37,6 +38,7 @@
 class MockAdmin : public fuchsia::device::manager::Administrator {
  public:
   bool suspend_called() { return suspend_called_; }
+  bool resume_called() { return resume_called_; }
 
  private:
   void Suspend(uint32_t flags, SuspendCallback callback) override {
@@ -46,7 +48,14 @@
     callback(ZX_OK);
   }
 
+  void Resume(fuchsia::device::manager::SystemPowerState state, ResumeCallback callback) override {
+    ASSERT_FALSE(resume_called_);
+    resume_called_ = true;
+    callback(ZX_OK);
+  }
+
   bool suspend_called_ = false;
+  bool resume_called_ = false;
 };
 
 class FactoryResetTest : public Test {
diff --git a/zircon/system/core/devmgr/devhost/core.cc b/zircon/system/core/devmgr/devhost/core.cc
index a439db9..e387b1c 100644
--- a/zircon/system/core/devmgr/devhost/core.cc
+++ b/zircon/system/core/devmgr/devhost/core.cc
@@ -3,11 +3,7 @@
 // found in the LICENSE file.
 
 #include <assert.h>
-#include <ddk/device.h>
-#include <ddk/driver.h>
 #include <errno.h>
-#include <fbl/auto_call.h>
-#include <fbl/auto_lock.h>
 #include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -20,10 +16,15 @@
 #include <zircon/syscalls.h>
 #include <zircon/types.h>
 
+#include <array>
 #include <atomic>
 #include <new>
 #include <utility>
-#include <array>
+
+#include <ddk/device.h>
+#include <ddk/driver.h>
+#include <fbl/auto_call.h>
+#include <fbl/auto_lock.h>
 
 #include "composite-device.h"
 #include "devhost.h"
@@ -81,7 +82,9 @@
 
 static zx_status_t default_suspend(void* ctx, uint32_t flags) { return ZX_ERR_NOT_SUPPORTED; }
 
-static zx_status_t default_resume(void* ctx, uint32_t flags) { return ZX_ERR_NOT_SUPPORTED; }
+static zx_status_t default_resume(void* ctx, uint32_t target_system_state) {
+  return ZX_ERR_NOT_SUPPORTED;
+}
 
 static zx_status_t default_rxrpc(void* ctx, zx_handle_t channel) { return ZX_ERR_NOT_SUPPORTED; }
 
@@ -453,7 +456,6 @@
   // Ask the devcoordinator to schedule the removal of this device and its children.
   devhost_schedule_remove(dev, unbind_self);
   return ZX_OK;
-
 }
 
 void devhost_device_unbind_reply(const fbl::RefPtr<zx_device_t>& dev) REQ_DM_LOCK {
@@ -567,8 +569,8 @@
   return dev->CloseOp(flags);
 }
 
-zx_status_t devhost_device_get_dev_power_state_from_mapping(const fbl::RefPtr<zx_device>& dev,
-                                    uint32_t flags, fuchsia_device_SystemPowerStateInfo* info) {
+zx_status_t devhost_device_get_dev_power_state_from_mapping(
+    const fbl::RefPtr<zx_device>& dev, uint32_t flags, fuchsia_device_SystemPowerStateInfo* info) {
   // TODO(ravoorir) : When the usage of suspend flags is replaced with
   // system power states, this function will not need the switch case.
   // Some suspend flags might be translated to system power states with
@@ -595,8 +597,8 @@
       return ZX_ERR_INVALID_ARGS;
   }
   const std::array<fuchsia_device_SystemPowerStateInfo,
-    fuchsia_device_manager_MAX_SYSTEM_POWER_STATES>& sys_power_states =
-                                        dev->GetSystemPowerStateMapping();
+                   fuchsia_device_manager_MAX_SYSTEM_POWER_STATES>& sys_power_states =
+      dev->GetSystemPowerStateMapping();
   *info = sys_power_states[sys_state];
   return ZX_OK;
 }
@@ -631,13 +633,42 @@
   return ZX_OK;
 }
 
+zx_status_t devhost_device_resume(const fbl::RefPtr<zx_device>& dev,
+                                  uint32_t target_system_state) REQ_DM_LOCK {
+  enum_lock_acquire();
+
+  zx_status_t status = ZX_ERR_NOT_SUPPORTED;
+  // If new suspend hook is implemented, prefer that.
+  if (dev->ops->resume_new) {
+    fuchsia_device_DevicePowerState out_state;
+    ApiAutoRelock relock;
+    const std::array<fuchsia_device_SystemPowerStateInfo,
+                     fuchsia_device_manager_MAX_SYSTEM_POWER_STATES>& sys_power_states =
+        dev->GetSystemPowerStateMapping();
+    status =
+        dev->ops->resume_new(dev->ctx, sys_power_states[target_system_state].dev_state, &out_state);
+  } else if (dev->ops->resume) {
+    // Invoke resume hook otherwise.
+    ApiAutoRelock relock;
+    status = dev->ops->resume(dev->ctx, target_system_state);
+  }
+
+  enum_lock_release();
+
+  // default_resume() returns ZX_ERR_NOT_SUPPORTED
+  if ((status != ZX_OK) && (status != ZX_ERR_NOT_SUPPORTED)) {
+    return status;
+  }
+  return ZX_OK;
+}
+
 zx_status_t devhost_device_suspend_new(const fbl::RefPtr<zx_device>& dev,
                                        fuchsia_device_DevicePowerState requested_state,
                                        fuchsia_device_DevicePowerState* out_state) {
   zx_status_t status = ZX_OK;
   if (dev->ops->suspend_new) {
-    status = dev->ops->suspend_new(dev->ctx, requested_state, false /* wake_configured */,
-                                   out_state);
+    status =
+        dev->ops->suspend_new(dev->ctx, requested_state, false /* wake_configured */, out_state);
   }
   return status;
 }
diff --git a/zircon/system/core/devmgr/devhost/devhost.h b/zircon/system/core/devmgr/devhost/devhost.h
index c74ecf8..9f7e7e4 100644
--- a/zircon/system/core/devmgr/devhost/devhost.h
+++ b/zircon/system/core/devmgr/devhost/devhost.h
@@ -161,6 +161,7 @@
 zx_status_t devhost_device_suspend_new(const fbl::RefPtr<zx_device_t>& dev,
                                        fuchsia_device_DevicePowerState requested_state,
                                        fuchsia_device_DevicePowerState *out_state);
+zx_status_t devhost_device_resume(const fbl::RefPtr<zx_device_t>& dev, uint32_t target_system_state) REQ_DM_LOCK;
 zx_status_t devhost_device_resume_new(const fbl::RefPtr<zx_device_t>& dev,
                                        fuchsia_device_DevicePowerState requested_state,
                                        fuchsia_device_DevicePowerState *out_state);
diff --git a/zircon/system/core/devmgr/devhost/device-controller-connection.cc b/zircon/system/core/devmgr/devhost/device-controller-connection.cc
index 182b322..de4e8f3 100644
--- a/zircon/system/core/devmgr/devhost/device-controller-connection.cc
+++ b/zircon/system/core/devmgr/devhost/device-controller-connection.cc
@@ -61,6 +61,15 @@
   completer.Reply(r);
 }
 
+void DeviceControllerConnection::Resume(uint32_t target_system_state, ResumeCompleter::Sync completer) {
+  zx_status_t r;
+  {
+    ApiAutoLock lock;
+    r = devhost_device_resume(this->dev(), target_system_state);
+  }
+  completer.Reply(r);
+}
+
 void DeviceControllerConnection::ConnectProxy(::zx::channel shadow,
                                               ConnectProxyCompleter::Sync _completer) {
   log(RPC_SDW, "devhost connect proxy rpc\n");
diff --git a/zircon/system/core/devmgr/devhost/device-controller-connection.h b/zircon/system/core/devmgr/devhost/device-controller-connection.h
index 55640013..c0608e5 100644
--- a/zircon/system/core/devmgr/devhost/device-controller-connection.h
+++ b/zircon/system/core/devmgr/devhost/device-controller-connection.h
@@ -43,6 +43,7 @@
   void ConnectProxy(::zx::channel shadow, ConnectProxyCompleter::Sync _completer) override;
   void RemoveDevice(RemoveDeviceCompleter::Sync _completer) override;
   void Suspend(uint32_t flags, SuspendCompleter::Sync _completer) override;
+  void Resume(uint32_t target_system_state, ResumeCompleter::Sync _completer) override;
   void Unbind(UnbindCompleter::Sync _completer) override;
   void CompleteRemoval(CompleteRemovalCompleter::Sync _completer) override;
   void CompleteCompatibilityTests(llcpp::fuchsia::device::manager::CompatibilityTestStatus status,
diff --git a/zircon/system/dev/test/ddk-power/test-driver-child.cc b/zircon/system/dev/test/ddk-power/test-driver-child.cc
index a95623e..7f2002f 100644
--- a/zircon/system/dev/test/ddk-power/test-driver-child.cc
+++ b/zircon/system/dev/test/ddk-power/test-driver-child.cc
@@ -2,6 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <fuchsia/device/power/test/llcpp/fidl.h>
+#include <lib/fdio/fd.h>
+#include <lib/fdio/fdio.h>
+#include <lib/fdio/namespace.h>
+#include <lib/fdio/spawn.h>
+#include <lib/fdio/unsafe.h>
+#include <lib/fdio/watcher.h>
+
 #include <ddk/binding.h>
 #include <ddk/debug.h>
 #include <ddk/device.h>
@@ -11,32 +19,22 @@
 #include <ddktl/fidl.h>
 #include <fbl/alloc_checker.h>
 #include <fbl/auto_call.h>
-#include <fuchsia/device/power/test/llcpp/fidl.h>
-#include <lib/fdio/fd.h>
-#include <lib/fdio/fdio.h>
-#include <lib/fdio/namespace.h>
-#include <lib/fdio/spawn.h>
-#include <lib/fdio/unsafe.h>
-#include <lib/fdio/watcher.h>
 
 using llcpp::fuchsia::device::DevicePowerStateInfo;
 using llcpp::fuchsia::device::power::test::TestDevice;
 
 class TestPowerDriverChild;
-using DeviceType = ddk::Device<TestPowerDriverChild, ddk::Unbindable, ddk::Messageable, ddk::SuspendableNew,
-                               ddk::ResumableNew>;
-class TestPowerDriverChild : public DeviceType,
-                             public TestDevice::Interface {
+using DeviceType = ddk::Device<TestPowerDriverChild, ddk::Unbindable, ddk::Messageable,
+                               ddk::SuspendableNew, ddk::ResumableNew>;
+class TestPowerDriverChild : public DeviceType, public TestDevice::Interface {
  public:
   TestPowerDriverChild(zx_device_t* parent) : DeviceType(parent) {}
   static zx_status_t Create(void* ctx, zx_device_t* device);
   zx_status_t Bind();
-  void DdkUnbind() {
-    DdkRemove();
-  }
+  void DdkUnbind() { DdkRemove(); }
 
   void AddDeviceWithPowerArgs(::fidl::VectorView<DevicePowerStateInfo> info,
-                                     AddDeviceWithPowerArgsCompleter::Sync completer) override;
+                              AddDeviceWithPowerArgsCompleter::Sync completer) override;
 
   void GetCurrentDevicePowerState(GetCurrentDevicePowerStateCompleter::Sync completer) override;
   zx_status_t DdkMessage(fidl_msg_t* msg, fidl_txn_t* txn) {
@@ -62,6 +60,7 @@
 
 zx_status_t TestPowerDriverChild::DdkResumeNew(uint8_t requested_state, uint8_t* out_state) {
   current_power_state_ = requested_state;
+  printf("MINE MINE Reached test-driver-child current_power_state: %d\n", current_power_state_);
   *out_state = requested_state;
   return ZX_OK;
 }
@@ -87,7 +86,7 @@
     states[i].system_wake_state = state_info[i].system_wake_state;
   }
   zx_status_t status = child2->DdkAdd("power-test-child-2", 0, nullptr, 0, 0, nullptr,
-                       ZX_HANDLE_INVALID, states.get(), count);
+                                      ZX_HANDLE_INVALID, states.get(), count);
   if (status != ZX_OK) {
     response.set_err(status);
   } else {
@@ -98,18 +97,18 @@
   completer.Reply(std::move(response));
 }
 
-void TestPowerDriverChild::GetCurrentDevicePowerState(GetCurrentDevicePowerStateCompleter::Sync completer) {
+void TestPowerDriverChild::GetCurrentDevicePowerState(
+    GetCurrentDevicePowerStateCompleter::Sync completer) {
   ::llcpp::fuchsia::device::power::test::TestDevice_GetCurrentDevicePowerState_Result result;
-  result.set_response(llcpp::fuchsia::device::power::test::TestDevice_GetCurrentDevicePowerState_Response{
-      .cur_state = static_cast<llcpp::fuchsia::device::DevicePowerState>(current_power_state_),
-  });
+  result.set_response(
+      llcpp::fuchsia::device::power::test::TestDevice_GetCurrentDevicePowerState_Response{
+          .cur_state = static_cast<llcpp::fuchsia::device::DevicePowerState>(current_power_state_),
+      });
 
   completer.Reply(std::move(result));
 }
 
-zx_status_t TestPowerDriverChild::Bind() {
-  return DdkAdd("power-test-child");
-}
+zx_status_t TestPowerDriverChild::Bind() { return DdkAdd("power-test-child"); }
 
 zx_status_t TestPowerDriverChild::Create(void* ctx, zx_device_t* device) {
   fbl::AllocChecker ac;
@@ -137,4 +136,4 @@
 ZIRCON_DRIVER_BEGIN(TestPowerChild, test_power_child_driver_ops, "zircon", "0.1", 1)
   BI_MATCH_IF(EQ, BIND_PROTOCOL, ZX_PROTOCOL_TEST_POWER_CHILD),
 ZIRCON_DRIVER_END(TestPowerChild)
-// clang-format on
+    // clang-format on
diff --git a/zircon/system/dev/test/ddk-power/test-driver.cc b/zircon/system/dev/test/ddk-power/test-driver.cc
index 99c2271..687a5c6 100644
--- a/zircon/system/dev/test/ddk-power/test-driver.cc
+++ b/zircon/system/dev/test/ddk-power/test-driver.cc
@@ -20,7 +20,7 @@
 
 class TestPowerDriver;
 using DeviceType =
-    ddk::Device<TestPowerDriver, ddk::Unbindable, ddk::Suspendable, ddk::Messageable>;
+    ddk::Device<TestPowerDriver, ddk::Unbindable, ddk::Suspendable, ddk::Resumable, ddk::Messageable>;
 class TestPowerDriver : public DeviceType,
                         public ddk::EmptyProtocol<ZX_PROTOCOL_TEST_POWER_CHILD>,
                         public TestDevice::Interface {
@@ -34,6 +34,11 @@
     current_power_state_ = DevicePowerState::DEVICE_POWER_STATE_D1;
     return ZX_OK;
   }
+  zx_status_t DdkResume(uint32_t flags) {
+    // Set current_power_state to indicate that resume is called.
+    current_power_state_ = DevicePowerState::DEVICE_POWER_STATE_D0;
+    return ZX_OK;
+  }
   void AddDeviceWithPowerArgs(::fidl::VectorView<DevicePowerStateInfo> info,
                               AddDeviceWithPowerArgsCompleter::Sync completer) override;
 
diff --git a/zircon/system/dev/test/ddk-power/test.cc b/zircon/system/dev/test/ddk-power/test.cc
index e755c2e..acd4b95 100644
--- a/zircon/system/dev/test/ddk-power/test.cc
+++ b/zircon/system/dev/test/ddk-power/test.cc
@@ -20,10 +20,10 @@
 using llcpp::fuchsia::device::DevicePowerStateInfo;
 using llcpp::fuchsia::device::MAX_DEVICE_POWER_STATES;
 using llcpp::fuchsia::device::SystemPowerStateInfo;
-using llcpp::fuchsia::device::power::test::TestDevice;
+using llcpp::fuchsia::device::manager::Administrator;
 using llcpp::fuchsia::device::manager::MAX_SYSTEM_POWER_STATES;
 using llcpp::fuchsia::device::manager::SystemPowerState;
-using llcpp::fuchsia::device::manager::Administrator;
+using llcpp::fuchsia::device::power::test::TestDevice;
 
 class PowerTestCase : public zxtest::Test {
  public:
@@ -501,8 +501,8 @@
   ASSERT_OK(fdio_service_connect_at(devmgr.svc_root_dir().get(), service_name, remote.release()));
   ASSERT_NE(devmgr.svc_root_dir().get(), ZX_HANDLE_INVALID);
 
-  auto suspend_result = Administrator::Call::Suspend(zx::unowned(local),
-                      ::llcpp::fuchsia::device::manager::SUSPEND_FLAG_REBOOT);
+  auto suspend_result = Administrator::Call::Suspend(
+      zx::unowned(local), ::llcpp::fuchsia::device::manager::SUSPEND_FLAG_REBOOT);
   ASSERT_OK(suspend_result.status());
   const auto &suspend_response = suspend_result.value();
   ASSERT_OK(suspend_response.status);
@@ -531,3 +531,103 @@
   ASSERT_EQ(parent_dev_suspend_response->result.response().cur_state,
             DevicePowerState::DEVICE_POWER_STATE_D1);
 }
+
+TEST_F(PowerTestCase, SystemResume) {
+  // Add Capabilities
+  DevicePowerStateInfo states[3];
+  states[0].state_id = DevicePowerState::DEVICE_POWER_STATE_D0;
+  states[0].is_supported = true;
+  states[0].restore_latency = 0;
+  states[1].state_id = DevicePowerState::DEVICE_POWER_STATE_D2;
+  states[1].is_supported = true;
+  states[1].restore_latency = 100;
+  states[2].state_id = DevicePowerState::DEVICE_POWER_STATE_D3COLD;
+  states[2].is_supported = true;
+  states[2].restore_latency = 1000;
+  AddChildWithPowerArgs(states, fbl::count_of(states));
+
+  ::fidl::Array<SystemPowerStateInfo, MAX_SYSTEM_POWER_STATES> mapping{};
+  for (size_t i = 0; i < MAX_SYSTEM_POWER_STATES; i++) {
+    mapping[i].dev_state = DevicePowerState::DEVICE_POWER_STATE_D2;
+    mapping[i].wakeup_enable = false;
+  }
+  mapping[static_cast<size_t>(SystemPowerState::SYSTEM_POWER_STATE_FULLY_ON)].dev_state =
+      DevicePowerState::DEVICE_POWER_STATE_D0;
+  auto update_result =
+      Controller::Call::UpdatePowerStateMapping(zx::unowned(child2_device_handle), mapping);
+  ASSERT_OK(update_result.status());
+  zx_status_t call_status = ZX_OK;
+  if (update_result->result.is_err()) {
+    call_status = update_result->result.err();
+  }
+  ASSERT_OK(call_status);
+
+  zx::channel local, remote;
+  ASSERT_OK(zx::channel::create(0, &local, &remote));
+
+  char service_name[100];
+  snprintf(service_name, sizeof(service_name), "svc/%s",
+           ::llcpp::fuchsia::device::manager::Administrator::Name);
+  ASSERT_OK(fdio_service_connect_at(devmgr.svc_root_dir().get(), service_name, remote.release()));
+  ASSERT_NE(devmgr.svc_root_dir().get(), ZX_HANDLE_INVALID);
+
+  auto suspend_result = Administrator::Call::Suspend(
+      zx::unowned(local), ::llcpp::fuchsia::device::manager::SUSPEND_FLAG_REBOOT);
+  ASSERT_OK(suspend_result.status());
+  const auto &suspend_response = suspend_result.value();
+  ASSERT_OK(suspend_response.status);
+
+  // Verify the child's DdkSuspendNew routine gets called.
+  auto child_dev_suspend_response =
+      TestDevice::Call::GetCurrentDevicePowerState(zx::unowned(child2_device_handle));
+  ASSERT_OK(child_dev_suspend_response.status());
+  call_status = ZX_OK;
+  if (child_dev_suspend_response->result.is_err()) {
+    call_status = child_dev_suspend_response->result.err();
+  }
+  ASSERT_OK(call_status);
+  ASSERT_EQ(child_dev_suspend_response->result.response().cur_state,
+            DevicePowerState::DEVICE_POWER_STATE_D2);
+
+  // Verify the parent'd DdkSuspend routine gets called.
+  auto parent_dev_suspend_response =
+      TestDevice::Call::GetCurrentDevicePowerState(zx::unowned(parent_device_handle));
+  ASSERT_OK(parent_dev_suspend_response.status());
+  call_status = ZX_OK;
+  if (parent_dev_suspend_response->result.is_err()) {
+    call_status = parent_dev_suspend_response->result.err();
+  }
+  ASSERT_OK(call_status);
+  ASSERT_EQ(parent_dev_suspend_response->result.response().cur_state,
+            DevicePowerState::DEVICE_POWER_STATE_D1);
+
+  auto resume_result = Administrator::Call::Resume(zx::unowned(local),
+                                                   SystemPowerState::SYSTEM_POWER_STATE_FULLY_ON);
+  ASSERT_OK(resume_result.status());
+  const auto &resume_response = resume_result.value();
+  ASSERT_OK(resume_response.status);
+
+  // Verify the child's DdkResumeNew routine gets called.
+  auto child_dev_resume_response =
+      TestDevice::Call::GetCurrentDevicePowerState(zx::unowned(child2_device_handle));
+  ASSERT_OK(child_dev_resume_response.status());
+  call_status = ZX_OK;
+  if (child_dev_resume_response->result.is_err()) {
+    call_status = child_dev_resume_response->result.err();
+  }
+  ASSERT_OK(call_status);
+  ASSERT_EQ(child_dev_resume_response->result.response().cur_state,
+            DevicePowerState::DEVICE_POWER_STATE_D0);
+
+  // Verify the parent'd DdkSuspend routine gets called.
+  auto parent_dev_resume_response =
+      TestDevice::Call::GetCurrentDevicePowerState(zx::unowned(parent_device_handle));
+  ASSERT_OK(parent_dev_resume_response.status());
+  call_status = ZX_OK;
+  if (parent_dev_resume_response->result.is_err()) {
+    call_status = parent_dev_resume_response->result.err();
+  }
+  ASSERT_OK(call_status);
+  ASSERT_EQ(parent_dev_resume_response->result.response().cur_state,
+            DevicePowerState::DEVICE_POWER_STATE_D0);
+}
diff --git a/zircon/system/fidl/fuchsia-device-manager/administrator.fidl b/zircon/system/fidl/fuchsia-device-manager/administrator.fidl
index eb139b3..2df38db 100644
--- a/zircon/system/fidl/fuchsia-device-manager/administrator.fidl
+++ b/zircon/system/fidl/fuchsia-device-manager/administrator.fidl
@@ -18,14 +18,15 @@
 // remove the suspend flags. For now, treat each suspend flag as a system
 // power state.
 enum SystemPowerState : uint8 {
-    SYSTEM_POWER_STATE_REBOOT = 0;
-    SYSTEM_POWER_STATE_REBOOT_BOOTLOADER = 1;
-    SYSTEM_POWER_STATE_REBOOT_RECOVERY = 2;
-    SYSTEM_POWER_STATE_POWEROFF = 3;
-    SYSTEM_POWER_STATE_MEXEC = 4;
-    SYSTEM_POWER_STATE_SUSPEND_RAM = 5;
+  SYSTEM_POWER_STATE_FULLY_ON = 0;
+  SYSTEM_POWER_STATE_REBOOT = 1;
+  SYSTEM_POWER_STATE_REBOOT_BOOTLOADER = 2;
+  SYSTEM_POWER_STATE_REBOOT_RECOVERY = 3;
+  SYSTEM_POWER_STATE_POWEROFF = 4;
+  SYSTEM_POWER_STATE_MEXEC = 5;
+  SYSTEM_POWER_STATE_SUSPEND_RAM = 6;
 };
-const uint32 MAX_SYSTEM_POWER_STATES = 6;
+const uint32 MAX_SYSTEM_POWER_STATES = 7;
 
 /// Provides administration services for the device manager service and the device tree it controls.
 [Discoverable, Layout = "Simple"]
@@ -33,4 +34,6 @@
     /// Ask all devices to enter the suspend state indicated by `flags`. Flags should be some
     /// combination of `DEVICE_SUSPEND_FLAG_*` from the DDK.
     Suspend(uint32 flags) -> (zx.status status);
+    /// Ask all devices to resume to active state indicated by the state.
+    Resume(SystemPowerState state) -> (zx.status status);
 };
diff --git a/zircon/system/fidl/fuchsia-device-manager/coordinator.fidl b/zircon/system/fidl/fuchsia-device-manager/coordinator.fidl
index db4a8db..334a985 100644
--- a/zircon/system/fidl/fuchsia-device-manager/coordinator.fidl
+++ b/zircon/system/fidl/fuchsia-device-manager/coordinator.fidl
@@ -117,6 +117,10 @@
     /// Ask devhost to suspend this device, using the target state indicated by `flags`.
     Suspend(uint32 flags) -> (zx.status status);
 
+    /// Ask devhost to resume this device, using the target system state indicated by
+    //'target_system_state'.
+    Resume(uint32 target_system_state) -> (zx.status status);
+
     /// Inform devhost about the compatibility test status when compatibility tests
     /// fail or complete successfully.
     // TODO(ravoorir) : This should be an asynchronous call from devhost to
diff --git a/zircon/system/fidl/fuchsia-device-manager/gen/llcpp/fidl.cc b/zircon/system/fidl/fuchsia-device-manager/gen/llcpp/fidl.cc
index 32c7cce..4c89533 100644
--- a/zircon/system/fidl/fuchsia-device-manager/gen/llcpp/fidl.cc
+++ b/zircon/system/fidl/fuchsia-device-manager/gen/llcpp/fidl.cc
@@ -391,6 +391,12 @@
 constexpr uint64_t kAdministrator_Suspend_GenOrdinal = 0x4bb44c32133da26elu;
 extern "C" const fidl_type_t fuchsia_device_manager_AdministratorSuspendRequestTable;
 extern "C" const fidl_type_t fuchsia_device_manager_AdministratorSuspendResponseTable;
+[[maybe_unused]]
+constexpr uint64_t kAdministrator_Resume_Ordinal = 0x3f61f33b00000000lu;
+[[maybe_unused]]
+constexpr uint64_t kAdministrator_Resume_GenOrdinal = 0x7e953b4960a4cbaelu;
+extern "C" const fidl_type_t fuchsia_device_manager_AdministratorResumeRequestTable;
+extern "C" const fidl_type_t fuchsia_device_manager_AdministratorResumeResponseTable;
 
 }  // namespace
 template <>
@@ -456,6 +462,69 @@
   return ::fidl::Decode(std::move(_call_result.message));
 }
 
+template <>
+Administrator::ResultOf::Resume_Impl<Administrator::ResumeResponse>::Resume_Impl(zx::unowned_channel _client_end, SystemPowerState state) {
+  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<ResumeRequest, ::fidl::MessageDirection::kSending>();
+  ::fidl::internal::AlignedBuffer<_kWriteAllocSize> _write_bytes_inlined;
+  auto& _write_bytes_array = _write_bytes_inlined;
+  uint8_t* _write_bytes = _write_bytes_array.view().data();
+  memset(_write_bytes, 0, ResumeRequest::PrimarySize);
+  auto& _request = *reinterpret_cast<ResumeRequest*>(_write_bytes);
+  _request.state = std::move(state);
+  ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(ResumeRequest));
+  ::fidl::DecodedMessage<ResumeRequest> _decoded_request(std::move(_request_bytes));
+  Super::SetResult(
+      Administrator::InPlace::Resume(std::move(_client_end), std::move(_decoded_request), Super::response_buffer()));
+}
+
+Administrator::ResultOf::Resume Administrator::SyncClient::Resume(SystemPowerState state) {
+  return ResultOf::Resume(zx::unowned_channel(this->channel_), std::move(state));
+}
+
+Administrator::ResultOf::Resume Administrator::Call::Resume(zx::unowned_channel _client_end, SystemPowerState state) {
+  return ResultOf::Resume(std::move(_client_end), std::move(state));
+}
+
+template <>
+Administrator::UnownedResultOf::Resume_Impl<Administrator::ResumeResponse>::Resume_Impl(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, SystemPowerState state, ::fidl::BytePart _response_buffer) {
+  if (_request_buffer.capacity() < ResumeRequest::PrimarySize) {
+    Super::SetFailure(::fidl::DecodeResult<ResumeResponse>(ZX_ERR_BUFFER_TOO_SMALL, ::fidl::internal::kErrorRequestBufferTooSmall));
+    return;
+  }
+  memset(_request_buffer.data(), 0, ResumeRequest::PrimarySize);
+  auto& _request = *reinterpret_cast<ResumeRequest*>(_request_buffer.data());
+  _request.state = std::move(state);
+  _request_buffer.set_actual(sizeof(ResumeRequest));
+  ::fidl::DecodedMessage<ResumeRequest> _decoded_request(std::move(_request_buffer));
+  Super::SetResult(
+      Administrator::InPlace::Resume(std::move(_client_end), std::move(_decoded_request), std::move(_response_buffer)));
+}
+
+Administrator::UnownedResultOf::Resume Administrator::SyncClient::Resume(::fidl::BytePart _request_buffer, SystemPowerState state, ::fidl::BytePart _response_buffer) {
+  return UnownedResultOf::Resume(zx::unowned_channel(this->channel_), std::move(_request_buffer), std::move(state), std::move(_response_buffer));
+}
+
+Administrator::UnownedResultOf::Resume Administrator::Call::Resume(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, SystemPowerState state, ::fidl::BytePart _response_buffer) {
+  return UnownedResultOf::Resume(std::move(_client_end), std::move(_request_buffer), std::move(state), std::move(_response_buffer));
+}
+
+::fidl::DecodeResult<Administrator::ResumeResponse> Administrator::InPlace::Resume(zx::unowned_channel _client_end, ::fidl::DecodedMessage<ResumeRequest> params, ::fidl::BytePart response_buffer) {
+  params.message()->_hdr = {};
+  params.message()->_hdr.ordinal = kAdministrator_Resume_Ordinal;
+  auto _encode_request_result = ::fidl::Encode(std::move(params));
+  if (_encode_request_result.status != ZX_OK) {
+    return ::fidl::DecodeResult<Administrator::ResumeResponse>::FromFailure(
+        std::move(_encode_request_result));
+  }
+  auto _call_result = ::fidl::Call<ResumeRequest, ResumeResponse>(
+    std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
+  if (_call_result.status != ZX_OK) {
+    return ::fidl::DecodeResult<Administrator::ResumeResponse>::FromFailure(
+        std::move(_call_result));
+  }
+  return ::fidl::Decode(std::move(_call_result.message));
+}
+
 
 bool Administrator::TryDispatch(Interface* impl, fidl_msg_t* msg, ::fidl::Transaction* txn) {
   if (msg->num_bytes < sizeof(fidl_message_header_t)) {
@@ -478,6 +547,19 @@
         Interface::SuspendCompleter::Sync(txn));
       return true;
     }
+    case kAdministrator_Resume_Ordinal:
+    case kAdministrator_Resume_GenOrdinal:
+    {
+      auto result = ::fidl::DecodeAs<ResumeRequest>(msg);
+      if (result.status != ZX_OK) {
+        txn->Close(ZX_ERR_INVALID_ARGS);
+        return true;
+      }
+      auto message = result.message.message();
+      impl->Resume(std::move(message->state),
+        Interface::ResumeCompleter::Sync(txn));
+      return true;
+    }
     default: {
       return false;
     }
@@ -523,6 +605,35 @@
 }
 
 
+void Administrator::Interface::ResumeCompleterBase::Reply(int32_t status) {
+  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<ResumeResponse, ::fidl::MessageDirection::kSending>();
+  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
+  auto& _response = *reinterpret_cast<ResumeResponse*>(_write_bytes);
+  _response._hdr.ordinal = kAdministrator_Resume_Ordinal;
+  _response.status = std::move(status);
+  ::fidl::BytePart _response_bytes(_write_bytes, _kWriteAllocSize, sizeof(ResumeResponse));
+  CompleterBase::SendReply(::fidl::DecodedMessage<ResumeResponse>(std::move(_response_bytes)));
+}
+
+void Administrator::Interface::ResumeCompleterBase::Reply(::fidl::BytePart _buffer, int32_t status) {
+  if (_buffer.capacity() < ResumeResponse::PrimarySize) {
+    CompleterBase::Close(ZX_ERR_INTERNAL);
+    return;
+  }
+  auto& _response = *reinterpret_cast<ResumeResponse*>(_buffer.data());
+  _response._hdr.ordinal = kAdministrator_Resume_Ordinal;
+  _response.status = std::move(status);
+  _buffer.set_actual(sizeof(ResumeResponse));
+  CompleterBase::SendReply(::fidl::DecodedMessage<ResumeResponse>(std::move(_buffer)));
+}
+
+void Administrator::Interface::ResumeCompleterBase::Reply(::fidl::DecodedMessage<ResumeResponse> params) {
+  params.message()->_hdr = {};
+  params.message()->_hdr.ordinal = kAdministrator_Resume_Ordinal;
+  CompleterBase::SendReply(std::move(params));
+}
+
+
 namespace {
 
 [[maybe_unused]]
@@ -1774,6 +1885,12 @@
 extern "C" const fidl_type_t fuchsia_device_manager_DeviceControllerSuspendRequestTable;
 extern "C" const fidl_type_t fuchsia_device_manager_DeviceControllerSuspendResponseTable;
 [[maybe_unused]]
+constexpr uint64_t kDeviceController_Resume_Ordinal = 0x4d69ba3300000000lu;
+[[maybe_unused]]
+constexpr uint64_t kDeviceController_Resume_GenOrdinal = 0x4f111286b7bd9caflu;
+extern "C" const fidl_type_t fuchsia_device_manager_DeviceControllerResumeRequestTable;
+extern "C" const fidl_type_t fuchsia_device_manager_DeviceControllerResumeResponseTable;
+[[maybe_unused]]
 constexpr uint64_t kDeviceController_CompleteCompatibilityTests_Ordinal = 0x475e367c00000000lu;
 [[maybe_unused]]
 constexpr uint64_t kDeviceController_CompleteCompatibilityTests_GenOrdinal = 0x3883342451945549lu;
@@ -2106,6 +2223,69 @@
   return ::fidl::Decode(std::move(_call_result.message));
 }
 
+template <>
+DeviceController::ResultOf::Resume_Impl<DeviceController::ResumeResponse>::Resume_Impl(zx::unowned_channel _client_end, uint32_t target_system_state) {
+  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<ResumeRequest, ::fidl::MessageDirection::kSending>();
+  ::fidl::internal::AlignedBuffer<_kWriteAllocSize> _write_bytes_inlined;
+  auto& _write_bytes_array = _write_bytes_inlined;
+  uint8_t* _write_bytes = _write_bytes_array.view().data();
+  memset(_write_bytes, 0, ResumeRequest::PrimarySize);
+  auto& _request = *reinterpret_cast<ResumeRequest*>(_write_bytes);
+  _request.target_system_state = std::move(target_system_state);
+  ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(ResumeRequest));
+  ::fidl::DecodedMessage<ResumeRequest> _decoded_request(std::move(_request_bytes));
+  Super::SetResult(
+      DeviceController::InPlace::Resume(std::move(_client_end), std::move(_decoded_request), Super::response_buffer()));
+}
+
+DeviceController::ResultOf::Resume DeviceController::SyncClient::Resume(uint32_t target_system_state) {
+  return ResultOf::Resume(zx::unowned_channel(this->channel_), std::move(target_system_state));
+}
+
+DeviceController::ResultOf::Resume DeviceController::Call::Resume(zx::unowned_channel _client_end, uint32_t target_system_state) {
+  return ResultOf::Resume(std::move(_client_end), std::move(target_system_state));
+}
+
+template <>
+DeviceController::UnownedResultOf::Resume_Impl<DeviceController::ResumeResponse>::Resume_Impl(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, uint32_t target_system_state, ::fidl::BytePart _response_buffer) {
+  if (_request_buffer.capacity() < ResumeRequest::PrimarySize) {
+    Super::SetFailure(::fidl::DecodeResult<ResumeResponse>(ZX_ERR_BUFFER_TOO_SMALL, ::fidl::internal::kErrorRequestBufferTooSmall));
+    return;
+  }
+  memset(_request_buffer.data(), 0, ResumeRequest::PrimarySize);
+  auto& _request = *reinterpret_cast<ResumeRequest*>(_request_buffer.data());
+  _request.target_system_state = std::move(target_system_state);
+  _request_buffer.set_actual(sizeof(ResumeRequest));
+  ::fidl::DecodedMessage<ResumeRequest> _decoded_request(std::move(_request_buffer));
+  Super::SetResult(
+      DeviceController::InPlace::Resume(std::move(_client_end), std::move(_decoded_request), std::move(_response_buffer)));
+}
+
+DeviceController::UnownedResultOf::Resume DeviceController::SyncClient::Resume(::fidl::BytePart _request_buffer, uint32_t target_system_state, ::fidl::BytePart _response_buffer) {
+  return UnownedResultOf::Resume(zx::unowned_channel(this->channel_), std::move(_request_buffer), std::move(target_system_state), std::move(_response_buffer));
+}
+
+DeviceController::UnownedResultOf::Resume DeviceController::Call::Resume(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, uint32_t target_system_state, ::fidl::BytePart _response_buffer) {
+  return UnownedResultOf::Resume(std::move(_client_end), std::move(_request_buffer), std::move(target_system_state), std::move(_response_buffer));
+}
+
+::fidl::DecodeResult<DeviceController::ResumeResponse> DeviceController::InPlace::Resume(zx::unowned_channel _client_end, ::fidl::DecodedMessage<ResumeRequest> params, ::fidl::BytePart response_buffer) {
+  params.message()->_hdr = {};
+  params.message()->_hdr.ordinal = kDeviceController_Resume_Ordinal;
+  auto _encode_request_result = ::fidl::Encode(std::move(params));
+  if (_encode_request_result.status != ZX_OK) {
+    return ::fidl::DecodeResult<DeviceController::ResumeResponse>::FromFailure(
+        std::move(_encode_request_result));
+  }
+  auto _call_result = ::fidl::Call<ResumeRequest, ResumeResponse>(
+    std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
+  if (_call_result.status != ZX_OK) {
+    return ::fidl::DecodeResult<DeviceController::ResumeResponse>::FromFailure(
+        std::move(_call_result));
+  }
+  return ::fidl::Decode(std::move(_call_result.message));
+}
+
 
 DeviceController::ResultOf::CompleteCompatibilityTests_Impl::CompleteCompatibilityTests_Impl(zx::unowned_channel _client_end, CompatibilityTestStatus status) {
   constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<CompleteCompatibilityTestsRequest, ::fidl::MessageDirection::kSending>();
@@ -2254,6 +2434,19 @@
         Interface::SuspendCompleter::Sync(txn));
       return true;
     }
+    case kDeviceController_Resume_Ordinal:
+    case kDeviceController_Resume_GenOrdinal:
+    {
+      auto result = ::fidl::DecodeAs<ResumeRequest>(msg);
+      if (result.status != ZX_OK) {
+        txn->Close(ZX_ERR_INVALID_ARGS);
+        return true;
+      }
+      auto message = result.message.message();
+      impl->Resume(std::move(message->target_system_state),
+        Interface::ResumeCompleter::Sync(txn));
+      return true;
+    }
     case kDeviceController_CompleteCompatibilityTests_Ordinal:
     case kDeviceController_CompleteCompatibilityTests_GenOrdinal:
     {
@@ -2343,6 +2536,35 @@
 }
 
 
+void DeviceController::Interface::ResumeCompleterBase::Reply(int32_t status) {
+  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<ResumeResponse, ::fidl::MessageDirection::kSending>();
+  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
+  auto& _response = *reinterpret_cast<ResumeResponse*>(_write_bytes);
+  _response._hdr.ordinal = kDeviceController_Resume_Ordinal;
+  _response.status = std::move(status);
+  ::fidl::BytePart _response_bytes(_write_bytes, _kWriteAllocSize, sizeof(ResumeResponse));
+  CompleterBase::SendReply(::fidl::DecodedMessage<ResumeResponse>(std::move(_response_bytes)));
+}
+
+void DeviceController::Interface::ResumeCompleterBase::Reply(::fidl::BytePart _buffer, int32_t status) {
+  if (_buffer.capacity() < ResumeResponse::PrimarySize) {
+    CompleterBase::Close(ZX_ERR_INTERNAL);
+    return;
+  }
+  auto& _response = *reinterpret_cast<ResumeResponse*>(_buffer.data());
+  _response._hdr.ordinal = kDeviceController_Resume_Ordinal;
+  _response.status = std::move(status);
+  _buffer.set_actual(sizeof(ResumeResponse));
+  CompleterBase::SendReply(::fidl::DecodedMessage<ResumeResponse>(std::move(_buffer)));
+}
+
+void DeviceController::Interface::ResumeCompleterBase::Reply(::fidl::DecodedMessage<ResumeResponse> params) {
+  params.message()->_hdr = {};
+  params.message()->_hdr.ordinal = kDeviceController_Resume_Ordinal;
+  CompleterBase::SendReply(std::move(params));
+}
+
+
 namespace {
 
 [[maybe_unused]]
diff --git a/zircon/system/fidl/fuchsia-device-manager/gen/llcpp/include/fuchsia/device/manager/llcpp/fidl.h b/zircon/system/fidl/fuchsia-device-manager/gen/llcpp/include/fuchsia/device/manager/llcpp/fidl.h
index 6ecb49e..e9f77b8 100644
--- a/zircon/system/fidl/fuchsia-device-manager/gen/llcpp/include/fuchsia/device/manager/llcpp/fidl.h
+++ b/zircon/system/fidl/fuchsia-device-manager/gen/llcpp/include/fuchsia/device/manager/llcpp/fidl.h
@@ -23,12 +23,13 @@
 namespace manager {
 
 enum class SystemPowerState : uint8_t {
-  SYSTEM_POWER_STATE_REBOOT = 0u,
-  SYSTEM_POWER_STATE_REBOOT_BOOTLOADER = 1u,
-  SYSTEM_POWER_STATE_REBOOT_RECOVERY = 2u,
-  SYSTEM_POWER_STATE_POWEROFF = 3u,
-  SYSTEM_POWER_STATE_MEXEC = 4u,
-  SYSTEM_POWER_STATE_SUSPEND_RAM = 5u,
+  SYSTEM_POWER_STATE_FULLY_ON = 0u,
+  SYSTEM_POWER_STATE_REBOOT = 1u,
+  SYSTEM_POWER_STATE_REBOOT_BOOTLOADER = 2u,
+  SYSTEM_POWER_STATE_REBOOT_RECOVERY = 3u,
+  SYSTEM_POWER_STATE_POWEROFF = 4u,
+  SYSTEM_POWER_STATE_MEXEC = 5u,
+  SYSTEM_POWER_STATE_SUSPEND_RAM = 6u,
 };
 
 
@@ -532,6 +533,8 @@
 
 extern "C" const fidl_type_t fuchsia_device_manager_AdministratorSuspendRequestTable;
 extern "C" const fidl_type_t fuchsia_device_manager_AdministratorSuspendResponseTable;
+extern "C" const fidl_type_t fuchsia_device_manager_AdministratorResumeRequestTable;
+extern "C" const fidl_type_t fuchsia_device_manager_AdministratorResumeResponseTable;
 
 // Provides administration services for the device manager service and the device tree it controls.
 class Administrator final {
@@ -567,6 +570,34 @@
     using ResponseType = SuspendResponse;
   };
 
+  struct ResumeResponse final {
+    FIDL_ALIGNDECL
+    fidl_message_header_t _hdr;
+    int32_t status;
+
+    static constexpr const fidl_type_t* Type = &fuchsia_device_manager_AdministratorResumeResponseTable;
+    static constexpr uint32_t MaxNumHandles = 0;
+    static constexpr uint32_t PrimarySize = 24;
+    static constexpr uint32_t MaxOutOfLine = 0;
+    static constexpr bool HasFlexibleEnvelope = false;
+    static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
+        ::fidl::internal::TransactionalMessageKind::kResponse;
+  };
+  struct ResumeRequest final {
+    FIDL_ALIGNDECL
+    fidl_message_header_t _hdr;
+    SystemPowerState state;
+
+    static constexpr const fidl_type_t* Type = &fuchsia_device_manager_AdministratorResumeRequestTable;
+    static constexpr uint32_t MaxNumHandles = 0;
+    static constexpr uint32_t PrimarySize = 24;
+    static constexpr uint32_t MaxOutOfLine = 0;
+    static constexpr bool HasFlexibleEnvelope = false;
+    static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
+        ::fidl::internal::TransactionalMessageKind::kRequest;
+    using ResponseType = ResumeResponse;
+  };
+
 
   // Collection of return types of FIDL calls in this interface.
   class ResultOf final {
@@ -588,9 +619,26 @@
       using Super::operator->;
       using Super::operator*;
     };
+    template <typename ResponseType>
+    class Resume_Impl final : private ::fidl::internal::OwnedSyncCallBase<ResponseType> {
+      using Super = ::fidl::internal::OwnedSyncCallBase<ResponseType>;
+     public:
+      Resume_Impl(zx::unowned_channel _client_end, SystemPowerState state);
+      ~Resume_Impl() = default;
+      Resume_Impl(Resume_Impl&& other) = default;
+      Resume_Impl& operator=(Resume_Impl&& other) = default;
+      using Super::status;
+      using Super::error;
+      using Super::ok;
+      using Super::Unwrap;
+      using Super::value;
+      using Super::operator->;
+      using Super::operator*;
+    };
 
    public:
     using Suspend = Suspend_Impl<SuspendResponse>;
+    using Resume = Resume_Impl<ResumeResponse>;
   };
 
   // Collection of return types of FIDL calls in this interface,
@@ -614,9 +662,26 @@
       using Super::operator->;
       using Super::operator*;
     };
+    template <typename ResponseType>
+    class Resume_Impl final : private ::fidl::internal::UnownedSyncCallBase<ResponseType> {
+      using Super = ::fidl::internal::UnownedSyncCallBase<ResponseType>;
+     public:
+      Resume_Impl(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, SystemPowerState state, ::fidl::BytePart _response_buffer);
+      ~Resume_Impl() = default;
+      Resume_Impl(Resume_Impl&& other) = default;
+      Resume_Impl& operator=(Resume_Impl&& other) = default;
+      using Super::status;
+      using Super::error;
+      using Super::ok;
+      using Super::Unwrap;
+      using Super::value;
+      using Super::operator->;
+      using Super::operator*;
+    };
 
    public:
     using Suspend = Suspend_Impl<SuspendResponse>;
+    using Resume = Resume_Impl<ResumeResponse>;
   };
 
   class SyncClient final {
@@ -640,6 +705,14 @@
     // Caller provides the backing storage for FIDL message via request and response buffers.
     UnownedResultOf::Suspend Suspend(::fidl::BytePart _request_buffer, uint32_t flags, ::fidl::BytePart _response_buffer);
 
+    // Ask all devices to resume to active state indicated by the state.
+    // Allocates 48 bytes of message buffer on the stack. No heap allocation necessary.
+    ResultOf::Resume Resume(SystemPowerState state);
+
+    // Ask all devices to resume to active state indicated by the state.
+    // Caller provides the backing storage for FIDL message via request and response buffers.
+    UnownedResultOf::Resume Resume(::fidl::BytePart _request_buffer, SystemPowerState state, ::fidl::BytePart _response_buffer);
+
    private:
     ::zx::channel channel_;
   };
@@ -659,6 +732,14 @@
     // Caller provides the backing storage for FIDL message via request and response buffers.
     static UnownedResultOf::Suspend Suspend(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, uint32_t flags, ::fidl::BytePart _response_buffer);
 
+    // Ask all devices to resume to active state indicated by the state.
+    // Allocates 48 bytes of message buffer on the stack. No heap allocation necessary.
+    static ResultOf::Resume Resume(zx::unowned_channel _client_end, SystemPowerState state);
+
+    // Ask all devices to resume to active state indicated by the state.
+    // Caller provides the backing storage for FIDL message via request and response buffers.
+    static UnownedResultOf::Resume Resume(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, SystemPowerState state, ::fidl::BytePart _response_buffer);
+
   };
 
   // Messages are encoded and decoded in-place when these methods are used.
@@ -671,6 +752,9 @@
     // combination of `DEVICE_SUSPEND_FLAG_*` from the DDK.
     static ::fidl::DecodeResult<SuspendResponse> Suspend(zx::unowned_channel _client_end, ::fidl::DecodedMessage<SuspendRequest> params, ::fidl::BytePart response_buffer);
 
+    // Ask all devices to resume to active state indicated by the state.
+    static ::fidl::DecodeResult<ResumeResponse> Resume(zx::unowned_channel _client_end, ::fidl::DecodedMessage<ResumeRequest> params, ::fidl::BytePart response_buffer);
+
   };
 
   // Pure-virtual interface to be implemented by a server.
@@ -695,6 +779,20 @@
 
     virtual void Suspend(uint32_t flags, SuspendCompleter::Sync _completer) = 0;
 
+    class ResumeCompleterBase : public _Base {
+     public:
+      void Reply(int32_t status);
+      void Reply(::fidl::BytePart _buffer, int32_t status);
+      void Reply(::fidl::DecodedMessage<ResumeResponse> params);
+
+     protected:
+      using ::fidl::CompleterBase::CompleterBase;
+    };
+
+    using ResumeCompleter = ::fidl::Completer<ResumeCompleterBase>;
+
+    virtual void Resume(SystemPowerState state, ResumeCompleter::Sync _completer) = 0;
+
   };
 
   // Attempts to dispatch the incoming message to a handler function in the server implementation.
@@ -736,7 +834,7 @@
 // Maximum number of bytes in a metadata payload
 constexpr uint32_t METADATA_MAX = 8192u;
 
-constexpr uint32_t MAX_SYSTEM_POWER_STATES = 6u;
+constexpr uint32_t MAX_SYSTEM_POWER_STATES = 7u;
 
 extern "C" const fidl_type_t fuchsia_device_manager_DevhostControllerCreateDeviceStubRequestTable;
 extern "C" const fidl_type_t fuchsia_device_manager_DevhostControllerCreateDeviceRequestTable;
@@ -2790,6 +2888,8 @@
 extern "C" const fidl_type_t fuchsia_device_manager_DeviceControllerConnectProxyRequestTable;
 extern "C" const fidl_type_t fuchsia_device_manager_DeviceControllerSuspendRequestTable;
 extern "C" const fidl_type_t fuchsia_device_manager_DeviceControllerSuspendResponseTable;
+extern "C" const fidl_type_t fuchsia_device_manager_DeviceControllerResumeRequestTable;
+extern "C" const fidl_type_t fuchsia_device_manager_DeviceControllerResumeResponseTable;
 extern "C" const fidl_type_t fuchsia_device_manager_DeviceControllerCompleteCompatibilityTestsRequestTable;
 
 // Protocol for controlling devices in a devhost process from the devcoordinator
@@ -2875,6 +2975,34 @@
     using ResponseType = SuspendResponse;
   };
 
+  struct ResumeResponse final {
+    FIDL_ALIGNDECL
+    fidl_message_header_t _hdr;
+    int32_t status;
+
+    static constexpr const fidl_type_t* Type = &fuchsia_device_manager_DeviceControllerResumeResponseTable;
+    static constexpr uint32_t MaxNumHandles = 0;
+    static constexpr uint32_t PrimarySize = 24;
+    static constexpr uint32_t MaxOutOfLine = 0;
+    static constexpr bool HasFlexibleEnvelope = false;
+    static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
+        ::fidl::internal::TransactionalMessageKind::kResponse;
+  };
+  struct ResumeRequest final {
+    FIDL_ALIGNDECL
+    fidl_message_header_t _hdr;
+    uint32_t target_system_state;
+
+    static constexpr const fidl_type_t* Type = &fuchsia_device_manager_DeviceControllerResumeRequestTable;
+    static constexpr uint32_t MaxNumHandles = 0;
+    static constexpr uint32_t PrimarySize = 24;
+    static constexpr uint32_t MaxOutOfLine = 0;
+    static constexpr bool HasFlexibleEnvelope = false;
+    static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
+        ::fidl::internal::TransactionalMessageKind::kRequest;
+    using ResponseType = ResumeResponse;
+  };
+
   struct CompleteCompatibilityTestsRequest final {
     FIDL_ALIGNDECL
     fidl_message_header_t _hdr;
@@ -2970,6 +3098,22 @@
       using Super::operator->;
       using Super::operator*;
     };
+    template <typename ResponseType>
+    class Resume_Impl final : private ::fidl::internal::OwnedSyncCallBase<ResponseType> {
+      using Super = ::fidl::internal::OwnedSyncCallBase<ResponseType>;
+     public:
+      Resume_Impl(zx::unowned_channel _client_end, uint32_t target_system_state);
+      ~Resume_Impl() = default;
+      Resume_Impl(Resume_Impl&& other) = default;
+      Resume_Impl& operator=(Resume_Impl&& other) = default;
+      using Super::status;
+      using Super::error;
+      using Super::ok;
+      using Super::Unwrap;
+      using Super::value;
+      using Super::operator->;
+      using Super::operator*;
+    };
     class CompleteCompatibilityTests_Impl final : private ::fidl::internal::StatusAndError {
       using Super = ::fidl::internal::StatusAndError;
      public:
@@ -2989,6 +3133,7 @@
     using CompleteRemoval = CompleteRemoval_Impl;
     using RemoveDevice = RemoveDevice_Impl;
     using Suspend = Suspend_Impl<SuspendResponse>;
+    using Resume = Resume_Impl<ResumeResponse>;
     using CompleteCompatibilityTests = CompleteCompatibilityTests_Impl;
   };
 
@@ -3073,6 +3218,22 @@
       using Super::operator->;
       using Super::operator*;
     };
+    template <typename ResponseType>
+    class Resume_Impl final : private ::fidl::internal::UnownedSyncCallBase<ResponseType> {
+      using Super = ::fidl::internal::UnownedSyncCallBase<ResponseType>;
+     public:
+      Resume_Impl(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, uint32_t target_system_state, ::fidl::BytePart _response_buffer);
+      ~Resume_Impl() = default;
+      Resume_Impl(Resume_Impl&& other) = default;
+      Resume_Impl& operator=(Resume_Impl&& other) = default;
+      using Super::status;
+      using Super::error;
+      using Super::ok;
+      using Super::Unwrap;
+      using Super::value;
+      using Super::operator->;
+      using Super::operator*;
+    };
     class CompleteCompatibilityTests_Impl final : private ::fidl::internal::StatusAndError {
       using Super = ::fidl::internal::StatusAndError;
      public:
@@ -3092,6 +3253,7 @@
     using CompleteRemoval = CompleteRemoval_Impl;
     using RemoveDevice = RemoveDevice_Impl;
     using Suspend = Suspend_Impl<SuspendResponse>;
+    using Resume = Resume_Impl<ResumeResponse>;
     using CompleteCompatibilityTests = CompleteCompatibilityTests_Impl;
   };
 
@@ -3159,6 +3321,14 @@
     // Caller provides the backing storage for FIDL message via request and response buffers.
     UnownedResultOf::Suspend Suspend(::fidl::BytePart _request_buffer, uint32_t flags, ::fidl::BytePart _response_buffer);
 
+    // Ask devhost to resume this device, using the target system state indicated by
+    // Allocates 48 bytes of message buffer on the stack. No heap allocation necessary.
+    ResultOf::Resume Resume(uint32_t target_system_state);
+
+    // Ask devhost to resume this device, using the target system state indicated by
+    // Caller provides the backing storage for FIDL message via request and response buffers.
+    UnownedResultOf::Resume Resume(::fidl::BytePart _request_buffer, uint32_t target_system_state, ::fidl::BytePart _response_buffer);
+
     // Inform devhost about the compatibility test status when compatibility tests
     // fail or complete successfully.
     // Allocates 24 bytes of message buffer on the stack. No heap allocation necessary.
@@ -3231,6 +3401,14 @@
     // Caller provides the backing storage for FIDL message via request and response buffers.
     static UnownedResultOf::Suspend Suspend(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, uint32_t flags, ::fidl::BytePart _response_buffer);
 
+    // Ask devhost to resume this device, using the target system state indicated by
+    // Allocates 48 bytes of message buffer on the stack. No heap allocation necessary.
+    static ResultOf::Resume Resume(zx::unowned_channel _client_end, uint32_t target_system_state);
+
+    // Ask devhost to resume this device, using the target system state indicated by
+    // Caller provides the backing storage for FIDL message via request and response buffers.
+    static UnownedResultOf::Resume Resume(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, uint32_t target_system_state, ::fidl::BytePart _response_buffer);
+
     // Inform devhost about the compatibility test status when compatibility tests
     // fail or complete successfully.
     // Allocates 24 bytes of message buffer on the stack. No heap allocation necessary.
@@ -3276,6 +3454,9 @@
     // Ask devhost to suspend this device, using the target state indicated by `flags`.
     static ::fidl::DecodeResult<SuspendResponse> Suspend(zx::unowned_channel _client_end, ::fidl::DecodedMessage<SuspendRequest> params, ::fidl::BytePart response_buffer);
 
+    // Ask devhost to resume this device, using the target system state indicated by
+    static ::fidl::DecodeResult<ResumeResponse> Resume(zx::unowned_channel _client_end, ::fidl::DecodedMessage<ResumeRequest> params, ::fidl::BytePart response_buffer);
+
     // Inform devhost about the compatibility test status when compatibility tests
     // fail or complete successfully.
     static ::fidl::internal::StatusAndError CompleteCompatibilityTests(zx::unowned_channel _client_end, ::fidl::DecodedMessage<CompleteCompatibilityTestsRequest> params);
@@ -3334,6 +3515,20 @@
 
     virtual void Suspend(uint32_t flags, SuspendCompleter::Sync _completer) = 0;
 
+    class ResumeCompleterBase : public _Base {
+     public:
+      void Reply(int32_t status);
+      void Reply(::fidl::BytePart _buffer, int32_t status);
+      void Reply(::fidl::DecodedMessage<ResumeResponse> params);
+
+     protected:
+      using ::fidl::CompleterBase::CompleterBase;
+    };
+
+    using ResumeCompleter = ::fidl::Completer<ResumeCompleterBase>;
+
+    virtual void Resume(uint32_t target_system_state, ResumeCompleter::Sync _completer) = 0;
+
     using CompleteCompatibilityTestsCompleter = ::fidl::Completer<>;
 
     virtual void CompleteCompatibilityTests(CompatibilityTestStatus status, CompleteCompatibilityTestsCompleter::Sync _completer) = 0;
@@ -5255,6 +5450,22 @@
 static_assert(offsetof(::llcpp::fuchsia::device::manager::Administrator::SuspendResponse, status) == 16);
 
 template <>
+struct IsFidlType<::llcpp::fuchsia::device::manager::Administrator::ResumeRequest> : public std::true_type {};
+template <>
+struct IsFidlMessage<::llcpp::fuchsia::device::manager::Administrator::ResumeRequest> : public std::true_type {};
+static_assert(sizeof(::llcpp::fuchsia::device::manager::Administrator::ResumeRequest)
+    == ::llcpp::fuchsia::device::manager::Administrator::ResumeRequest::PrimarySize);
+static_assert(offsetof(::llcpp::fuchsia::device::manager::Administrator::ResumeRequest, state) == 16);
+
+template <>
+struct IsFidlType<::llcpp::fuchsia::device::manager::Administrator::ResumeResponse> : public std::true_type {};
+template <>
+struct IsFidlMessage<::llcpp::fuchsia::device::manager::Administrator::ResumeResponse> : public std::true_type {};
+static_assert(sizeof(::llcpp::fuchsia::device::manager::Administrator::ResumeResponse)
+    == ::llcpp::fuchsia::device::manager::Administrator::ResumeResponse::PrimarySize);
+static_assert(offsetof(::llcpp::fuchsia::device::manager::Administrator::ResumeResponse, status) == 16);
+
+template <>
 struct IsFidlType<::llcpp::fuchsia::device::manager::DevhostController::CreateDeviceStubRequest> : public std::true_type {};
 template <>
 struct IsFidlMessage<::llcpp::fuchsia::device::manager::DevhostController::CreateDeviceStubRequest> : public std::true_type {};
@@ -5490,6 +5701,22 @@
 static_assert(offsetof(::llcpp::fuchsia::device::manager::DeviceController::SuspendResponse, status) == 16);
 
 template <>
+struct IsFidlType<::llcpp::fuchsia::device::manager::DeviceController::ResumeRequest> : public std::true_type {};
+template <>
+struct IsFidlMessage<::llcpp::fuchsia::device::manager::DeviceController::ResumeRequest> : public std::true_type {};
+static_assert(sizeof(::llcpp::fuchsia::device::manager::DeviceController::ResumeRequest)
+    == ::llcpp::fuchsia::device::manager::DeviceController::ResumeRequest::PrimarySize);
+static_assert(offsetof(::llcpp::fuchsia::device::manager::DeviceController::ResumeRequest, target_system_state) == 16);
+
+template <>
+struct IsFidlType<::llcpp::fuchsia::device::manager::DeviceController::ResumeResponse> : public std::true_type {};
+template <>
+struct IsFidlMessage<::llcpp::fuchsia::device::manager::DeviceController::ResumeResponse> : public std::true_type {};
+static_assert(sizeof(::llcpp::fuchsia::device::manager::DeviceController::ResumeResponse)
+    == ::llcpp::fuchsia::device::manager::DeviceController::ResumeResponse::PrimarySize);
+static_assert(offsetof(::llcpp::fuchsia::device::manager::DeviceController::ResumeResponse, status) == 16);
+
+template <>
 struct IsFidlType<::llcpp::fuchsia::device::manager::DeviceController::CompleteCompatibilityTestsRequest> : public std::true_type {};
 template <>
 struct IsFidlMessage<::llcpp::fuchsia::device::manager::DeviceController::CompleteCompatibilityTestsRequest> : public std::true_type {};
diff --git a/zircon/system/fidl/fuchsia-device/gen/llcpp/fidl.cc b/zircon/system/fidl/fuchsia-device/gen/llcpp/fidl.cc
index 361cecd..da936967 100644
--- a/zircon/system/fidl/fuchsia-device/gen/llcpp/fidl.cc
+++ b/zircon/system/fidl/fuchsia-device/gen/llcpp/fidl.cc
@@ -1307,7 +1307,7 @@
 }
 
 template <>
-Controller::ResultOf::UpdatePowerStateMapping_Impl<Controller::UpdatePowerStateMappingResponse>::UpdatePowerStateMapping_Impl(zx::unowned_channel _client_end, ::fidl::Array<SystemPowerStateInfo, 6> mapping) {
+Controller::ResultOf::UpdatePowerStateMapping_Impl<Controller::UpdatePowerStateMappingResponse>::UpdatePowerStateMapping_Impl(zx::unowned_channel _client_end, ::fidl::Array<SystemPowerStateInfo, 7> mapping) {
   constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<UpdatePowerStateMappingRequest, ::fidl::MessageDirection::kSending>();
   ::fidl::internal::AlignedBuffer<_kWriteAllocSize> _write_bytes_inlined;
   auto& _write_bytes_array = _write_bytes_inlined;
@@ -1321,16 +1321,16 @@
       Controller::InPlace::UpdatePowerStateMapping(std::move(_client_end), std::move(_decoded_request), Super::response_buffer()));
 }
 
-Controller::ResultOf::UpdatePowerStateMapping Controller::SyncClient::UpdatePowerStateMapping(::fidl::Array<SystemPowerStateInfo, 6> mapping) {
+Controller::ResultOf::UpdatePowerStateMapping Controller::SyncClient::UpdatePowerStateMapping(::fidl::Array<SystemPowerStateInfo, 7> mapping) {
   return ResultOf::UpdatePowerStateMapping(zx::unowned_channel(this->channel_), std::move(mapping));
 }
 
-Controller::ResultOf::UpdatePowerStateMapping Controller::Call::UpdatePowerStateMapping(zx::unowned_channel _client_end, ::fidl::Array<SystemPowerStateInfo, 6> mapping) {
+Controller::ResultOf::UpdatePowerStateMapping Controller::Call::UpdatePowerStateMapping(zx::unowned_channel _client_end, ::fidl::Array<SystemPowerStateInfo, 7> mapping) {
   return ResultOf::UpdatePowerStateMapping(std::move(_client_end), std::move(mapping));
 }
 
 template <>
-Controller::UnownedResultOf::UpdatePowerStateMapping_Impl<Controller::UpdatePowerStateMappingResponse>::UpdatePowerStateMapping_Impl(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::fidl::Array<SystemPowerStateInfo, 6> mapping, ::fidl::BytePart _response_buffer) {
+Controller::UnownedResultOf::UpdatePowerStateMapping_Impl<Controller::UpdatePowerStateMappingResponse>::UpdatePowerStateMapping_Impl(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::fidl::Array<SystemPowerStateInfo, 7> mapping, ::fidl::BytePart _response_buffer) {
   if (_request_buffer.capacity() < UpdatePowerStateMappingRequest::PrimarySize) {
     Super::SetFailure(::fidl::DecodeResult<UpdatePowerStateMappingResponse>(ZX_ERR_BUFFER_TOO_SMALL, ::fidl::internal::kErrorRequestBufferTooSmall));
     return;
@@ -1344,11 +1344,11 @@
       Controller::InPlace::UpdatePowerStateMapping(std::move(_client_end), std::move(_decoded_request), std::move(_response_buffer)));
 }
 
-Controller::UnownedResultOf::UpdatePowerStateMapping Controller::SyncClient::UpdatePowerStateMapping(::fidl::BytePart _request_buffer, ::fidl::Array<SystemPowerStateInfo, 6> mapping, ::fidl::BytePart _response_buffer) {
+Controller::UnownedResultOf::UpdatePowerStateMapping Controller::SyncClient::UpdatePowerStateMapping(::fidl::BytePart _request_buffer, ::fidl::Array<SystemPowerStateInfo, 7> mapping, ::fidl::BytePart _response_buffer) {
   return UnownedResultOf::UpdatePowerStateMapping(zx::unowned_channel(this->channel_), std::move(_request_buffer), std::move(mapping), std::move(_response_buffer));
 }
 
-Controller::UnownedResultOf::UpdatePowerStateMapping Controller::Call::UpdatePowerStateMapping(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::fidl::Array<SystemPowerStateInfo, 6> mapping, ::fidl::BytePart _response_buffer) {
+Controller::UnownedResultOf::UpdatePowerStateMapping Controller::Call::UpdatePowerStateMapping(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::fidl::Array<SystemPowerStateInfo, 7> mapping, ::fidl::BytePart _response_buffer) {
   return UnownedResultOf::UpdatePowerStateMapping(std::move(_client_end), std::move(_request_buffer), std::move(mapping), std::move(_response_buffer));
 }
 
@@ -2230,7 +2230,7 @@
   ::fidl::BytePart _response_bytes(_write_bytes, _kWriteAllocSize, sizeof(GetPowerStateMappingResponse));
   CompleterBase::SendReply(::fidl::DecodedMessage<GetPowerStateMappingResponse>(std::move(_response_bytes)));
 }
-void Controller::Interface::GetPowerStateMappingCompleterBase::ReplySuccess(::fidl::Array<SystemPowerStateInfo, 6> mapping) {
+void Controller::Interface::GetPowerStateMappingCompleterBase::ReplySuccess(::fidl::Array<SystemPowerStateInfo, 7> mapping) {
   Controller_GetPowerStateMapping_Response response;
   response.mapping = std::move(mapping);
 
@@ -2251,7 +2251,7 @@
   _buffer.set_actual(sizeof(GetPowerStateMappingResponse));
   CompleterBase::SendReply(::fidl::DecodedMessage<GetPowerStateMappingResponse>(std::move(_buffer)));
 }
-void Controller::Interface::GetPowerStateMappingCompleterBase::ReplySuccess(::fidl::BytePart _buffer, ::fidl::Array<SystemPowerStateInfo, 6> mapping) {
+void Controller::Interface::GetPowerStateMappingCompleterBase::ReplySuccess(::fidl::BytePart _buffer, ::fidl::Array<SystemPowerStateInfo, 7> mapping) {
   Controller_GetPowerStateMapping_Response response;
   response.mapping = std::move(mapping);
 
diff --git a/zircon/system/fidl/fuchsia-device/gen/llcpp/include/fuchsia/device/llcpp/fidl.h b/zircon/system/fidl/fuchsia-device/gen/llcpp/include/fuchsia/device/llcpp/fidl.h
index cecbf18..b353b97 100644
--- a/zircon/system/fidl/fuchsia-device/gen/llcpp/include/fuchsia/device/llcpp/fidl.h
+++ b/zircon/system/fidl/fuchsia-device/gen/llcpp/include/fuchsia/device/llcpp/fidl.h
@@ -365,11 +365,11 @@
 struct Controller_GetPowerStateMapping_Response {
   static constexpr const fidl_type_t* Type = &fuchsia_device_Controller_GetPowerStateMapping_ResponseTable;
   static constexpr uint32_t MaxNumHandles = 0;
-  static constexpr uint32_t PrimarySize = 48;
+  static constexpr uint32_t PrimarySize = 56;
   [[maybe_unused]]
   static constexpr uint32_t MaxOutOfLine = 0;
 
-  ::fidl::Array<SystemPowerStateInfo, 6> mapping = {};
+  ::fidl::Array<SystemPowerStateInfo, 7> mapping = {};
 };
 
 extern "C" const fidl_type_t fuchsia_device_Controller_GetPowerStateMapping_ResultTable;
@@ -452,7 +452,7 @@
 
   static constexpr const fidl_type_t* Type = &fuchsia_device_Controller_GetPowerStateMapping_ResultTable;
   static constexpr uint32_t MaxNumHandles = 0;
-  static constexpr uint32_t PrimarySize = 52;
+  static constexpr uint32_t PrimarySize = 60;
   [[maybe_unused]]
   static constexpr uint32_t MaxOutOfLine = 0;
 
@@ -1104,11 +1104,11 @@
   struct UpdatePowerStateMappingRequest final {
     FIDL_ALIGNDECL
     fidl_message_header_t _hdr;
-    ::fidl::Array<SystemPowerStateInfo, 6> mapping;
+    ::fidl::Array<SystemPowerStateInfo, 7> mapping;
 
     static constexpr const fidl_type_t* Type = &fuchsia_device_ControllerUpdatePowerStateMappingRequestTable;
     static constexpr uint32_t MaxNumHandles = 0;
-    static constexpr uint32_t PrimarySize = 64;
+    static constexpr uint32_t PrimarySize = 72;
     static constexpr uint32_t MaxOutOfLine = 0;
     static constexpr bool HasFlexibleEnvelope = false;
     static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
@@ -1123,7 +1123,7 @@
 
     static constexpr const fidl_type_t* Type = &fuchsia_device_ControllerGetPowerStateMappingResponseTable;
     static constexpr uint32_t MaxNumHandles = 0;
-    static constexpr uint32_t PrimarySize = 72;
+    static constexpr uint32_t PrimarySize = 80;
     static constexpr uint32_t MaxOutOfLine = 0;
     static constexpr bool HasFlexibleEnvelope = false;
     static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
@@ -1389,7 +1389,7 @@
     class UpdatePowerStateMapping_Impl final : private ::fidl::internal::OwnedSyncCallBase<ResponseType> {
       using Super = ::fidl::internal::OwnedSyncCallBase<ResponseType>;
      public:
-      UpdatePowerStateMapping_Impl(zx::unowned_channel _client_end, ::fidl::Array<SystemPowerStateInfo, 6> mapping);
+      UpdatePowerStateMapping_Impl(zx::unowned_channel _client_end, ::fidl::Array<SystemPowerStateInfo, 7> mapping);
       ~UpdatePowerStateMapping_Impl() = default;
       UpdatePowerStateMapping_Impl(UpdatePowerStateMapping_Impl&& other) = default;
       UpdatePowerStateMapping_Impl& operator=(UpdatePowerStateMapping_Impl&& other) = default;
@@ -1670,7 +1670,7 @@
     class UpdatePowerStateMapping_Impl final : private ::fidl::internal::UnownedSyncCallBase<ResponseType> {
       using Super = ::fidl::internal::UnownedSyncCallBase<ResponseType>;
      public:
-      UpdatePowerStateMapping_Impl(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::fidl::Array<SystemPowerStateInfo, 6> mapping, ::fidl::BytePart _response_buffer);
+      UpdatePowerStateMapping_Impl(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::fidl::Array<SystemPowerStateInfo, 7> mapping, ::fidl::BytePart _response_buffer);
       ~UpdatePowerStateMapping_Impl() = default;
       UpdatePowerStateMapping_Impl(UpdatePowerStateMapping_Impl&& other) = default;
       UpdatePowerStateMapping_Impl& operator=(UpdatePowerStateMapping_Impl&& other) = default;
@@ -1873,17 +1873,17 @@
 
     // Updates the mapping between system power states to device power states. Used by the system
     // wide power manager to manage power for this device
-    // Allocates 88 bytes of message buffer on the stack. No heap allocation necessary.
-    ResultOf::UpdatePowerStateMapping UpdatePowerStateMapping(::fidl::Array<SystemPowerStateInfo, 6> mapping);
+    // Allocates 96 bytes of message buffer on the stack. No heap allocation necessary.
+    ResultOf::UpdatePowerStateMapping UpdatePowerStateMapping(::fidl::Array<SystemPowerStateInfo, 7> mapping);
 
     // Updates the mapping between system power states to device power states. Used by the system
     // wide power manager to manage power for this device
     // Caller provides the backing storage for FIDL message via request and response buffers.
-    UnownedResultOf::UpdatePowerStateMapping UpdatePowerStateMapping(::fidl::BytePart _request_buffer, ::fidl::Array<SystemPowerStateInfo, 6> mapping, ::fidl::BytePart _response_buffer);
+    UnownedResultOf::UpdatePowerStateMapping UpdatePowerStateMapping(::fidl::BytePart _request_buffer, ::fidl::Array<SystemPowerStateInfo, 7> mapping, ::fidl::BytePart _response_buffer);
 
     // Get the mapping between system power states to device power states. Used by the system
     // wide power manager to manage power for this device.
-    // Allocates 88 bytes of message buffer on the stack. No heap allocation necessary.
+    // Allocates 96 bytes of message buffer on the stack. No heap allocation necessary.
     ResultOf::GetPowerStateMapping GetPowerStateMapping();
 
     // Get the mapping between system power states to device power states. Used by the system
@@ -2030,17 +2030,17 @@
 
     // Updates the mapping between system power states to device power states. Used by the system
     // wide power manager to manage power for this device
-    // Allocates 88 bytes of message buffer on the stack. No heap allocation necessary.
-    static ResultOf::UpdatePowerStateMapping UpdatePowerStateMapping(zx::unowned_channel _client_end, ::fidl::Array<SystemPowerStateInfo, 6> mapping);
+    // Allocates 96 bytes of message buffer on the stack. No heap allocation necessary.
+    static ResultOf::UpdatePowerStateMapping UpdatePowerStateMapping(zx::unowned_channel _client_end, ::fidl::Array<SystemPowerStateInfo, 7> mapping);
 
     // Updates the mapping between system power states to device power states. Used by the system
     // wide power manager to manage power for this device
     // Caller provides the backing storage for FIDL message via request and response buffers.
-    static UnownedResultOf::UpdatePowerStateMapping UpdatePowerStateMapping(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::fidl::Array<SystemPowerStateInfo, 6> mapping, ::fidl::BytePart _response_buffer);
+    static UnownedResultOf::UpdatePowerStateMapping UpdatePowerStateMapping(zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::fidl::Array<SystemPowerStateInfo, 7> mapping, ::fidl::BytePart _response_buffer);
 
     // Get the mapping between system power states to device power states. Used by the system
     // wide power manager to manage power for this device.
-    // Allocates 88 bytes of message buffer on the stack. No heap allocation necessary.
+    // Allocates 96 bytes of message buffer on the stack. No heap allocation necessary.
     static ResultOf::GetPowerStateMapping GetPowerStateMapping(zx::unowned_channel _client_end);
 
     // Get the mapping between system power states to device power states. Used by the system
@@ -2328,15 +2328,15 @@
 
     using UpdatePowerStateMappingCompleter = ::fidl::Completer<UpdatePowerStateMappingCompleterBase>;
 
-    virtual void UpdatePowerStateMapping(::fidl::Array<SystemPowerStateInfo, 6> mapping, UpdatePowerStateMappingCompleter::Sync _completer) = 0;
+    virtual void UpdatePowerStateMapping(::fidl::Array<SystemPowerStateInfo, 7> mapping, UpdatePowerStateMappingCompleter::Sync _completer) = 0;
 
     class GetPowerStateMappingCompleterBase : public _Base {
      public:
       void Reply(Controller_GetPowerStateMapping_Result result);
-      void ReplySuccess(::fidl::Array<SystemPowerStateInfo, 6> mapping);
+      void ReplySuccess(::fidl::Array<SystemPowerStateInfo, 7> mapping);
       void ReplyError(int32_t error);
       void Reply(::fidl::BytePart _buffer, Controller_GetPowerStateMapping_Result result);
-      void ReplySuccess(::fidl::BytePart _buffer, ::fidl::Array<SystemPowerStateInfo, 6> mapping);
+      void ReplySuccess(::fidl::BytePart _buffer, ::fidl::Array<SystemPowerStateInfo, 7> mapping);
       void Reply(::fidl::DecodedMessage<GetPowerStateMappingResponse> params);
 
      protected: