[FDF]Remove old suspend hook

All the drivers have been moved to use new suspend hook. This change
removes the old suspend hook.

Test: fx make-integration-patch. fx run-test coordinator_tests.

Change-Id: I9e561e047af91715c5a143f2ff6158e5d40e480b
diff --git a/docs/concepts/drivers/using-ddktl.md b/docs/concepts/drivers/using-ddktl.md
index 6c8e6ec..f2a7a65 100644
--- a/docs/concepts/drivers/using-ddktl.md
+++ b/docs/concepts/drivers/using-ddktl.md
@@ -36,7 +36,6 @@
 
 Deprecated Mixin class      | Function             | Purpose
 ----------------------------|----------------------|------------------------------
-`ddk::Suspendable`          | **DdkSuspend()**     | to suspend device
 `ddk::Resumable`            | **DdkResume()**      | to resume device
 `ddk::Readable`             | **DdkRead()**        | client's **read()**
 `ddk::Writable`             | **DdkWrite()**       | client's **write()**
diff --git a/src/devices/host/core.cc b/src/devices/host/core.cc
index 0f7c416..ca9ad10 100644
--- a/src/devices/host/core.cc
+++ b/src/devices/host/core.cc
@@ -69,7 +69,8 @@
 static zx_status_t default_close(void* ctx, uint32_t flags) { return ZX_OK; }
 
 static void default_unbind(void* ctx) {}
-
+static void default_suspend(void* ctx, uint8_t requested_state, bool enable_wake,
+                            uint8_t suspend_reason) {}
 static void default_release(void* ctx) {}
 
 static zx_status_t default_read(void* ctx, void* buf, size_t count, zx_off_t off, size_t* actual) {
@@ -83,8 +84,6 @@
 
 static zx_off_t default_get_size(void* ctx) { return 0; }
 
-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 target_system_state) {
   return ZX_ERR_NOT_SUPPORTED;
 }
@@ -112,8 +111,8 @@
   ops.read = default_read;
   ops.write = default_write;
   ops.get_size = default_get_size;
-  ops.suspend = default_suspend;
   ops.resume = default_resume;
+  ops.suspend_new = default_suspend;
   ops.rxrpc = default_rxrpc;
   ops.message = default_message;
   ops.set_performance_state = default_set_performance_state;
@@ -131,6 +130,8 @@
   ops.open = +[](void* ctx, zx_device_t**, uint32_t) -> zx_status_t { device_invalid_fatal(ctx); };
   ops.close = +[](void* ctx, uint32_t) -> zx_status_t { device_invalid_fatal(ctx); };
   ops.unbind = +[](void* ctx) { device_invalid_fatal(ctx); };
+  ops.suspend_new = +[](void* ctx, uint8_t requested_state, bool enable_wake,
+                        uint8_t suspend_reason) { device_invalid_fatal(ctx); };
   ops.release = +[](void* ctx) { device_invalid_fatal(ctx); };
   ops.read =
       +[](void* ctx, void*, size_t, size_t, size_t*) -> zx_status_t { device_invalid_fatal(ctx); };
@@ -138,7 +139,6 @@
     device_invalid_fatal(ctx);
   };
   ops.get_size = +[](void* ctx) -> zx_off_t { device_invalid_fatal(ctx); };
-  ops.suspend = +[](void* ctx, uint32_t) -> zx_status_t { device_invalid_fatal(ctx); };
   ops.resume = +[](void* ctx, uint32_t) -> zx_status_t { device_invalid_fatal(ctx); };
   ops.rxrpc = +[](void* ctx, zx_handle_t) -> zx_status_t { device_invalid_fatal(ctx); };
   ops.message =
@@ -465,12 +465,11 @@
   return ZX_OK;
 }
 
-void devhost_device_init_reply(const fbl::RefPtr<zx_device_t>& dev,
-                               zx_status_t status,
+void devhost_device_init_reply(const fbl::RefPtr<zx_device_t>& dev, zx_status_t status,
                                const device_init_reply_args_t* args) REQ_DM_LOCK {
   if (!(dev->flags & DEV_FLAG_INITIALIZING)) {
-    ZX_PANIC("device: %p(%s): cannot reply to init, flags are: (%x)\n",
-             dev.get(), dev->name, dev->flags);
+    ZX_PANIC("device: %p(%s): cannot reply to init, flags are: (%x)\n", dev.get(), dev->name,
+             dev->flags);
   }
   if (status == ZX_OK) {
     if (args && args->power_states && args->power_state_count != 0) {
@@ -483,8 +482,8 @@
   if (dev->init_cb) {
     dev->init_cb(status);
   } else {
-    ZX_PANIC("device: %p(%s): cannot reply to init, no callback set, flags are 0x%x\n",
-             dev.get(), dev->name, dev->flags);
+    ZX_PANIC("device: %p(%s): cannot reply to init, no callback set, flags are 0x%x\n", dev.get(),
+             dev->name, dev->flags);
   }
 }
 
@@ -714,29 +713,27 @@
                                      fuchsia_device_DevicePowerState_DEVICE_POWER_STATE_D0);
     log(INFO, "Devhost: system suspend overriding auto suspend for %s\n", dev->name);
   }
-  enum_lock_acquire();
   zx_status_t status = ZX_ERR_NOT_SUPPORTED;
   // If new suspend hook is implemented, prefer that.
   if (dev->ops->suspend_new) {
     ::llcpp::fuchsia::device::SystemPowerStateInfo new_state_info;
     uint8_t suspend_reason = DEVICE_SUSPEND_REASON_SELECTIVE_SUSPEND;
-    ApiAutoRelock relock;
+
     status = devhost_device_get_dev_power_state_from_mapping(dev, flags, &new_state_info,
                                                              &suspend_reason);
     if (status == ZX_OK) {
-      dev->ops->suspend_new(dev->ctx, static_cast<uint8_t>(new_state_info.dev_state),
-                            new_state_info.wakeup_enable, suspend_reason);
+      enum_lock_acquire();
+      {
+        ApiAutoRelock relock;
+        dev->ops->suspend_new(dev->ctx, static_cast<uint8_t>(new_state_info.dev_state),
+                              new_state_info.wakeup_enable, suspend_reason);
+      }
+      enum_lock_release();
       return;
     }
-  } else if (dev->ops->suspend) {
-    // Invoke suspend hook otherwise.
-    ApiAutoRelock relock;
-    status = dev->ops->suspend(dev->ctx, flags);
   }
 
-  enum_lock_release();
-
-  // default_suspend() returns ZX_ERR_NOT_SUPPORTED
+  // If suspend hook is not implemented, do not throw error during system suspend.
   if (status == ZX_ERR_NOT_SUPPORTED) {
     status = ZX_OK;
   }
diff --git a/src/devices/host/devfs-connection.cc b/src/devices/host/devfs-connection.cc
index 89f7f6f..4675cc8 100644
--- a/src/devices/host/devfs-connection.cc
+++ b/src/devices/host/devfs-connection.cc
@@ -213,10 +213,6 @@
   completer.Reply(ZX_OK);
 }
 
-void DevfsConnection::DebugSuspend(DebugSuspendCompleter::Sync completer) {
-  completer.Reply(this->dev->SuspendOp(0));
-}
-
 void DevfsConnection::DebugResume(DebugResumeCompleter::Sync completer) {
   completer.Reply(this->dev->ResumeOp(0));
 }
diff --git a/src/devices/host/devfs-connection.h b/src/devices/host/devfs-connection.h
index 01f4ee4..d0c4c33 100644
--- a/src/devices/host/devfs-connection.h
+++ b/src/devices/host/devfs-connection.h
@@ -84,7 +84,6 @@
   void GetDevicePerformanceStates(GetDevicePerformanceStatesCompleter::Sync completer) override;
   void SetDriverLogFlags(uint32_t clear_flags, uint32_t set_flags,
                          SetDriverLogFlagsCompleter::Sync _completer) override;
-  void DebugSuspend(DebugSuspendCompleter::Sync _completer) override;
   void DebugResume(DebugResumeCompleter::Sync _completer) override;
   void RunCompatibilityTests(int64_t hook_wait_time,
                              RunCompatibilityTestsCompleter::Sync _completer) override;
@@ -156,9 +155,7 @@
   return reinterpret_cast<Connection*>(txn);
 }
 
-inline Connection Connection::CopyTxn(fidl_txn_t* txn) {
-  return *FromTxn(txn);
-}
+inline Connection Connection::CopyTxn(fidl_txn_t* txn) { return *FromTxn(txn); }
 
 class Transaction : public fidl::Transaction {
  public:
diff --git a/src/devices/host/zx-device.h b/src/devices/host/zx-device.h
index 283b00a..db0ff1d 100644
--- a/src/devices/host/zx-device.h
+++ b/src/devices/host/zx-device.h
@@ -66,10 +66,6 @@
 
   void ReleaseOp() { Dispatch(ops->release); }
 
-  zx_status_t SuspendOp(uint32_t flags) {
-    return Dispatch(ops->suspend, ZX_ERR_NOT_SUPPORTED, flags);
-  }
-
   void SuspendNewOp(uint8_t requested_state, bool enable_wake, uint8_t suspend_reason) {
     Dispatch(ops->suspend_new, requested_state, enable_wake, suspend_reason);
   }
diff --git a/src/devices/tests/libdriver-integration-test/mock-device-hooks.cc b/src/devices/tests/libdriver-integration-test/mock-device-hooks.cc
index 78553fc..87ff3fd 100644
--- a/src/devices/tests/libdriver-integration-test/mock-device-hooks.cc
+++ b/src/devices/tests/libdriver-integration-test/mock-device-hooks.cc
@@ -92,11 +92,12 @@
   TryFinish();
 }
 
-void UnorderedHooks::Suspend(HookInvocation record, uint32_t flags, SuspendCallback callback) {
+void UnorderedHooks::Suspend(HookInvocation record, uint8_t requested_state, bool enable_wake,
+                             uint8_t suspend_reason, SuspendCallback callback) {
   if (!suspend_) {
     return Fail(__FUNCTION__);
   }
-  callback(action_list_finalizer_(suspend_(record, flags)));
+  callback(action_list_finalizer_(suspend_(record, requested_state, enable_wake, suspend_reason)));
   suspend_ = nullptr;
   TryFinish();
 }
diff --git a/src/devices/tests/libdriver-integration-test/mock-device-hooks.h b/src/devices/tests/libdriver-integration-test/mock-device-hooks.h
index be1f10e..062071a5 100644
--- a/src/devices/tests/libdriver-integration-test/mock-device-hooks.h
+++ b/src/devices/tests/libdriver-integration-test/mock-device-hooks.h
@@ -4,16 +4,17 @@
 
 #pragma once
 
+#include <fuchsia/device/mock/cpp/fidl.h>
+#include <lib/fidl/coding.h>
+#include <lib/fit/bridge.h>
+#include <lib/fit/function.h>
+#include <lib/zx/channel.h>
+
 #include <string>
 #include <utility>
 #include <vector>
 
-#include <fuchsia/device/mock/cpp/fidl.h>
 #include <gtest/gtest.h>
-#include <lib/fidl/coding.h>
-#include <lib/fit/function.h>
-#include <lib/fit/bridge.h>
-#include <lib/zx/channel.h>
 
 #include "action-list.h"
 
@@ -57,7 +58,8 @@
 
   void GetSize(HookInvocation record, GetSizeCallback callback) override { Fail(__FUNCTION__); }
 
-  void Suspend(HookInvocation record, uint32_t flags, SuspendCallback callback) override {
+  void Suspend(HookInvocation record, uint8_t requested_state, bool enable_wake,
+               uint8_t suspend_reason, SuspendCallback callback) override {
     Fail(__FUNCTION__);
   }
 
@@ -71,6 +73,7 @@
 
   void AddDeviceDone(uint64_t action_id) final { ZX_ASSERT(false); }
   void UnbindReplyDone(uint64_t action_id) final { ZX_ASSERT(false); }
+  void SuspendReplyDone(uint64_t action_id) final { ZX_ASSERT(false); }
 
   virtual ~MockDeviceHooks() = default;
 
@@ -207,7 +210,8 @@
   void Write(HookInvocation record, std::vector<uint8_t> buffer, zx_off_t off,
              WriteCallback callback) override;
   void GetSize(HookInvocation record, GetSizeCallback callback) override;
-  void Suspend(HookInvocation record, uint32_t flags, SuspendCallback callback) override;
+  void Suspend(HookInvocation record, uint8_t requested_state, bool enable_wake,
+               uint8_t suspend_reason, SuspendCallback callback) override;
   void Resume(HookInvocation record, uint32_t flags, ResumeCallback callback) override;
   void Message(HookInvocation record, MessageCallback callback) override;
   void Rxrpc(HookInvocation record, RxrpcCallback callback) override;
@@ -227,7 +231,7 @@
   fit::function<ActionList(HookInvocation, uint64_t, zx_off_t)> read_;
   fit::function<ActionList(HookInvocation, std::vector<uint8_t>, zx_off_t)> write_;
   fit::function<ActionList(HookInvocation)> get_size_;
-  fit::function<ActionList(HookInvocation, uint32_t)> suspend_;
+  fit::function<ActionList(HookInvocation, uint8_t requested_state, bool enable_wake, uint8_t suspend_reason)> suspend_;
   fit::function<ActionList(HookInvocation, uint32_t)> resume_;
   fit::function<ActionList(HookInvocation)> message_;
   fit::function<ActionList(HookInvocation)> rxrpc_;
diff --git a/src/devices/tests/libdriver-integration-test/mock-device-thread.cc b/src/devices/tests/libdriver-integration-test/mock-device-thread.cc
index eb7586b..d376deb 100644
--- a/src/devices/tests/libdriver-integration-test/mock-device-thread.cc
+++ b/src/devices/tests/libdriver-integration-test/mock-device-thread.cc
@@ -11,6 +11,7 @@
   auto handler = [this](uint64_t action_id) { EventDone(action_id); };
   interface_.events().AddDeviceDone = handler;
   interface_.events().UnbindReplyDone = handler;
+  interface_.events().SuspendReplyDone = handler;
 }
 
 void MockDeviceThread::EventDone(uint64_t action_id) {
diff --git a/src/devices/tests/libdriver-integration-test/mock-device.cc b/src/devices/tests/libdriver-integration-test/mock-device.cc
index d5f45bc..e225a0a 100644
--- a/src/devices/tests/libdriver-integration-test/mock-device.cc
+++ b/src/devices/tests/libdriver-integration-test/mock-device.cc
@@ -50,8 +50,9 @@
   hooks_->GetSize(record, std::move(callback));
 }
 
-void MockDevice::Suspend(HookInvocation record, uint32_t flags, SuspendCallback callback) {
-  hooks_->Suspend(record, flags, std::move(callback));
+void MockDevice::Suspend(HookInvocation record, uint8_t requested_state, bool enable_wake,
+                         uint8_t suspend_reason, SuspendCallback callback) {
+  hooks_->Suspend(record, requested_state, enable_wake, suspend_reason, std::move(callback));
 }
 
 void MockDevice::Resume(HookInvocation record, uint32_t flags, ResumeCallback callback) {
@@ -76,6 +77,8 @@
 
 void MockDevice::UnbindReplyDone(uint64_t action_id) { AddDeviceDone(action_id); }
 
+void MockDevice::SuspendReplyDone(uint64_t action_id) { AddDeviceDone(action_id); }
+
 std::vector<ActionList::Action> MockDevice::FinalizeActionList(ActionList action_list) {
   return action_list.FinalizeActionList(&pending_actions_, &next_action_id_);
 }
diff --git a/src/devices/tests/libdriver-integration-test/mock-device.h b/src/devices/tests/libdriver-integration-test/mock-device.h
index d9d3eb7..27e4f1c8 100644
--- a/src/devices/tests/libdriver-integration-test/mock-device.h
+++ b/src/devices/tests/libdriver-integration-test/mock-device.h
@@ -4,13 +4,13 @@
 
 #pragma once
 
-#include <memory>
-#include <utility>
-
 #include <fuchsia/device/mock/cpp/fidl.h>
-#include <lib/zx/channel.h>
 #include <lib/fidl/cpp/binding.h>
 #include <lib/fidl/cpp/message.h>
+#include <lib/zx/channel.h>
+
+#include <memory>
+#include <utility>
 
 #include "action-list.h"
 #include "mock-device-hooks.h"
@@ -46,13 +46,15 @@
   void Write(HookInvocation record, std::vector<uint8_t> buffer, uint64_t off,
              WriteCallback callback) override;
   void GetSize(HookInvocation record, GetSizeCallback callback) override;
-  void Suspend(HookInvocation record, uint32_t flags, SuspendCallback callback) override;
+  void Suspend(HookInvocation record, uint8_t requested_state, bool enable_wake,
+               uint8_t suspend_reason, SuspendCallback callback) override;
   void Resume(HookInvocation record, uint32_t flags, ResumeCallback callback) override;
   void Message(HookInvocation record, MessageCallback callback) override;
   void Rxrpc(HookInvocation record, RxrpcCallback callback) override;
 
   void AddDeviceDone(uint64_t action_id) override;
   void UnbindReplyDone(uint64_t action_id) override;
+  void SuspendReplyDone(uint64_t action_id) override;
 
  private:
   // The buffers inside of |msg_out| must be allocated by the caller.
diff --git a/zircon/system/dev/test/ddk-power/test-driver.cc b/zircon/system/dev/test/ddk-power/test-driver.cc
index d8b6128..0a1baf6 100644
--- a/zircon/system/dev/test/ddk-power/test-driver.cc
+++ b/zircon/system/dev/test/ddk-power/test-driver.cc
@@ -21,7 +21,7 @@
 
 class TestPowerDriver;
 using DeviceType =
-    ddk::Device<TestPowerDriver, ddk::UnbindableNew, ddk::Suspendable, ddk::Messageable>;
+    ddk::Device<TestPowerDriver, ddk::UnbindableNew, ddk::SuspendableNew, ddk::Messageable>;
 class TestPowerDriver : public DeviceType,
                         public ddk::EmptyProtocol<ZX_PROTOCOL_TEST_POWER_CHILD>,
                         public TestDevice::Interface {
@@ -30,10 +30,9 @@
   zx_status_t Bind();
   void DdkUnbindNew(ddk::UnbindTxn txn) { txn.Reply(); }
   void DdkRelease() { delete this; }
-  zx_status_t DdkSuspend(uint32_t flags) {
-    // Set current_power_state to indicate that the suspend is called.
-    current_power_state_ = DevicePowerState::DEVICE_POWER_STATE_D1;
-    return ZX_OK;
+  void DdkSuspendNew(ddk::SuspendTxn txn) {
+    current_power_state_ = static_cast<DevicePowerState>(txn.requested_state());
+    txn.Reply(ZX_OK, txn.requested_state());
   }
   void AddDeviceWithPowerArgs(::fidl::VectorView<DevicePowerStateInfo> info,
                               ::fidl::VectorView<DevicePerformanceStateInfo> perf_states,
@@ -54,7 +53,7 @@
 
  private:
   DevicePowerState current_power_state_ = DevicePowerState::DEVICE_POWER_STATE_D0;
-  uint32_t current_performance_state_ = 0;
+  uint8_t current_performance_state_ = 0;
   bool auto_suspend_enabled_ = false;
   DevicePowerState deepest_autosuspend_sleep_state_ = DevicePowerState::DEVICE_POWER_STATE_D0;
 };
diff --git a/zircon/system/dev/test/ddk-power/test.cc b/zircon/system/dev/test/ddk-power/test.cc
index bb2dc0b..be6a206 100644
--- a/zircon/system/dev/test/ddk-power/test.cc
+++ b/zircon/system/dev/test/ddk-power/test.cc
@@ -785,7 +785,7 @@
   }
   ASSERT_OK(call_status);
   ASSERT_EQ(parent_dev_suspend_response->result.response().cur_state,
-            DevicePowerState::DEVICE_POWER_STATE_D1);
+            DevicePowerState::DEVICE_POWER_STATE_D3COLD);
 }
 
 TEST_F(PowerTestCase, Resume_Success) {
@@ -1009,7 +1009,6 @@
   ASSERT_FALSE(states_mapping[static_cast<uint8_t>(SystemPowerState::SYSTEM_POWER_STATE_REBOOT)]
                    .wakeup_enable);
 }
-
 TEST_F(PowerTestCase, SystemSuspend) {
   // Add Capabilities
   DevicePowerStateInfo states[3];
@@ -1088,5 +1087,5 @@
   }
   ASSERT_OK(call_status);
   ASSERT_EQ(parent_dev_suspend_response->result.response().cur_state,
-            DevicePowerState::DEVICE_POWER_STATE_D1);
+            DevicePowerState::DEVICE_POWER_STATE_D3COLD);
 }
diff --git a/zircon/system/dev/test/mock-device/device.cc b/zircon/system/dev/test/mock-device/device.cc
index 37ce3c5..94779c3 100644
--- a/zircon/system/dev/test/mock-device/device.cc
+++ b/zircon/system/dev/test/mock-device/device.cc
@@ -27,6 +27,7 @@
 #include <fbl/mutex.h>
 #include <fbl/vector.h>
 
+#include "ddktl/suspend-txn.h"
 #include "fidl.h"
 
 namespace mock_device {
@@ -51,7 +52,7 @@
   zx_status_t DdkWrite(const void* buf, size_t count, zx_off_t off, size_t* actual);
   zx_off_t DdkGetSize();
   zx_status_t DdkMessage(fidl_msg_t* msg, fidl_txn_t* txn);
-  zx_status_t DdkSuspend(uint32_t flags);
+  void DdkSuspendNew(ddk::SuspendTxn txn);
   zx_status_t DdkResume(uint32_t flags);
   zx_status_t DdkRxrpc(zx_handle_t channel);
 
@@ -114,6 +115,8 @@
   bool is_thread = false;
   // IN: The txn used to reply to the unbind hook.
   std::optional<ddk::UnbindTxn> pending_unbind_txn = std::nullopt;
+  // IN: The txn used to reply to the suspend hook.
+  std::optional<ddk::SuspendTxn> pending_suspend_txn = std::nullopt;
 };
 
 // Execute the actions returned by a hook
@@ -200,18 +203,17 @@
   // Launch a thread to do the actual joining and delete, since this could get
   // called from a thread.
   thrd_t thrd;
-  int ret = thrd_create(
-      &thrd,
-      [](void* arg) {
-        auto me = static_cast<MockDevice*>(arg);
-        fbl::AutoLock guard(&me->lock_);
-        for (auto& t : me->threads_) {
-          thrd_join(t, nullptr);
-        }
-        delete me;
-        return 0;
-      },
-      this);
+  int ret = thrd_create(&thrd,
+                        [](void* arg) {
+                          auto me = static_cast<MockDevice*>(arg);
+                          fbl::AutoLock guard(&me->lock_);
+                          for (auto& t : me->threads_) {
+                            thrd_join(t, nullptr);
+                          }
+                          delete me;
+                          return 0;
+                        },
+                        this);
   ZX_ASSERT(ret == thrd_success);
   thrd_detach(thrd);
 }
@@ -295,13 +297,14 @@
   return ctx.hook_status;
 }
 
-zx_status_t MockDevice::DdkSuspend(uint32_t flags) {
-  auto result = controller_.Suspend(ConstructHookInvocation(), flags);
+void MockDevice::DdkSuspendNew(ddk::SuspendTxn txn) {
+  auto result = controller_.Suspend(ConstructHookInvocation(), txn.requested_state(),
+                                    txn.enable_wake(), txn.suspend_reason());
   ZX_ASSERT(result.ok());
   ProcessActionsContext ctx(controller_.channel(), true, this, zxdev());
+  ctx.pending_suspend_txn = std::move(txn);
   zx_status_t status = ProcessActions(std::move(result->actions), &ctx);
   ZX_ASSERT(status == ZX_OK);
-  return ctx.hook_status;
 }
 
 zx_status_t MockDevice::DdkResume(uint32_t flags) {
@@ -398,6 +401,25 @@
         ZX_ASSERT(status == ZX_OK);
         break;
       }
+
+      case device_mock::Action::Tag::kSuspendReply: {
+        if (!ctx->pending_suspend_txn) {
+          printf("MockDevice::SuspendReply: asked to reply to unbind but no unbind is pending\n");
+          return ZX_ERR_INVALID_ARGS;
+        }
+        ctx->pending_suspend_txn->Reply(ZX_OK, 0);
+        zx_status_t status;
+        if (ctx->is_thread) {
+          status = device_mock::MockDeviceThread::SendSuspendReplyDoneEvent(
+              zx::unowned_channel(*ctx->channel), action.suspend_reply().action_id);
+        } else {
+          status = device_mock::MockDevice::Call::SuspendReplyDone(
+                       zx::unowned_channel(*ctx->channel), action.suspend_reply().action_id)
+                       .status();
+        }
+        ZX_ASSERT(status == ZX_OK);
+        break;
+      }
       case device_mock::Action::Tag::kAddDevice: {
         // TODO(teisenbe): Implement more functionality here
         auto& add_device_action = action.mutable_add_device();
diff --git a/zircon/system/dev/test/mock-device/gen/llcpp/fidl.cc b/zircon/system/dev/test/mock-device/gen/llcpp/fidl.cc
index 438d715..a811de0 100644
--- a/zircon/system/dev/test/mock-device/gen/llcpp/fidl.cc
+++ b/zircon/system/dev/test/mock-device/gen/llcpp/fidl.cc
@@ -35,6 +35,12 @@
 constexpr uint64_t kMockDeviceThread_UnbindReplyDone_GenOrdinal = 0x7cadbb1dcfd931b3lu;
 extern "C" const fidl_type_t v1_fuchsia_device_mock_MockDeviceThreadUnbindReplyDoneRequestTable;
 extern "C" const fidl_type_t v1_fuchsia_device_mock_MockDeviceThreadUnbindReplyDoneEventTable;
+[[maybe_unused]]
+constexpr uint64_t kMockDeviceThread_SuspendReplyDone_Ordinal = 0x17b00f4e00000000lu;
+[[maybe_unused]]
+constexpr uint64_t kMockDeviceThread_SuspendReplyDone_GenOrdinal = 0x158f6f5c096bef9elu;
+extern "C" const fidl_type_t v1_fuchsia_device_mock_MockDeviceThreadSuspendReplyDoneRequestTable;
+extern "C" const fidl_type_t v1_fuchsia_device_mock_MockDeviceThreadSuspendReplyDoneEventTable;
 
 }  // namespace
 
@@ -124,6 +130,9 @@
     if (::fidl::internal::ClampedMessageSize<UnbindReplyDoneResponse, ::fidl::MessageDirection::kReceiving>() >= x) {
       x = ::fidl::internal::ClampedMessageSize<UnbindReplyDoneResponse, ::fidl::MessageDirection::kReceiving>();
     }
+    if (::fidl::internal::ClampedMessageSize<SuspendReplyDoneResponse, ::fidl::MessageDirection::kReceiving>() >= x) {
+      x = ::fidl::internal::ClampedMessageSize<SuspendReplyDoneResponse, ::fidl::MessageDirection::kReceiving>();
+    }
     return x;
   })();
   constexpr uint32_t kHandleAllocSize = ([]() constexpr {
@@ -134,6 +143,9 @@
     if (UnbindReplyDoneResponse::MaxNumHandles >= x) {
       x = UnbindReplyDoneResponse::MaxNumHandles;
     }
+    if (SuspendReplyDoneResponse::MaxNumHandles >= x) {
+      x = SuspendReplyDoneResponse::MaxNumHandles;
+    }
     if (x > ZX_CHANNEL_MAX_MSG_HANDLES) {
       x = ZX_CHANNEL_MAX_MSG_HANDLES;
     }
@@ -193,6 +205,16 @@
       auto message = result.message.message();
       return handlers.unbind_reply_done(std::move(message->action_id));
     }
+    case kMockDeviceThread_SuspendReplyDone_Ordinal:
+    case kMockDeviceThread_SuspendReplyDone_GenOrdinal:
+    {
+      auto result = ::fidl::DecodeAs<SuspendReplyDoneResponse>(&msg);
+      if (result.status != ZX_OK) {
+        return result.status;
+      }
+      auto message = result.message.message();
+      return handlers.suspend_reply_done(std::move(message->action_id));
+    }
     default:
       zx_handle_close_many(read_handles, actual_handles);
       return handlers.unknown();
@@ -311,6 +333,41 @@
 }
 
 
+zx_status_t MockDeviceThread::SendSuspendReplyDoneEvent(::zx::unowned_channel _chan, uint64_t action_id) {
+  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<SuspendReplyDoneResponse, ::fidl::MessageDirection::kSending>();
+  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
+  auto& _response = *reinterpret_cast<SuspendReplyDoneResponse*>(_write_bytes);
+  MockDeviceThread::SetTransactionHeaderFor::SuspendReplyDoneResponse(
+      ::fidl::DecodedMessage<SuspendReplyDoneResponse>(
+          ::fidl::BytePart(reinterpret_cast<uint8_t*>(&_response),
+              SuspendReplyDoneResponse::PrimarySize,
+              SuspendReplyDoneResponse::PrimarySize)));
+  _response.action_id = std::move(action_id);
+  ::fidl::BytePart _response_bytes(_write_bytes, _kWriteAllocSize, sizeof(SuspendReplyDoneResponse));
+  return ::fidl::Write(::zx::unowned_channel(_chan), ::fidl::DecodedMessage<SuspendReplyDoneResponse>(std::move(_response_bytes)));
+}
+
+zx_status_t MockDeviceThread::SendSuspendReplyDoneEvent(::zx::unowned_channel _chan, ::fidl::BytePart _buffer, uint64_t action_id) {
+  if (_buffer.capacity() < SuspendReplyDoneResponse::PrimarySize) {
+    return ZX_ERR_BUFFER_TOO_SMALL;
+  }
+  auto& _response = *reinterpret_cast<SuspendReplyDoneResponse*>(_buffer.data());
+  MockDeviceThread::SetTransactionHeaderFor::SuspendReplyDoneResponse(
+      ::fidl::DecodedMessage<SuspendReplyDoneResponse>(
+          ::fidl::BytePart(reinterpret_cast<uint8_t*>(&_response),
+              SuspendReplyDoneResponse::PrimarySize,
+              SuspendReplyDoneResponse::PrimarySize)));
+  _response.action_id = std::move(action_id);
+  _buffer.set_actual(sizeof(SuspendReplyDoneResponse));
+  return ::fidl::Write(::zx::unowned_channel(_chan), ::fidl::DecodedMessage<SuspendReplyDoneResponse>(std::move(_buffer)));
+}
+
+zx_status_t MockDeviceThread::SendSuspendReplyDoneEvent(::zx::unowned_channel _chan, ::fidl::DecodedMessage<SuspendReplyDoneResponse> params) {
+  MockDeviceThread::SetTransactionHeaderFor::SuspendReplyDoneResponse(params);
+  return ::fidl::Write(::zx::unowned_channel(_chan), std::move(params));
+}
+
+
 
 void MockDeviceThread::SetTransactionHeaderFor::PerformActionsRequest(const ::fidl::DecodedMessage<MockDeviceThread::PerformActionsRequest>& _msg) {
   fidl_init_txn_header(&_msg.message()->_hdr, 0, kMockDeviceThread_PerformActions_GenOrdinal);
@@ -327,6 +384,11 @@
   _msg.message()->_hdr.flags[0] |= FIDL_TXN_HEADER_UNION_FROM_XUNION_FLAG;
 }
 
+void MockDeviceThread::SetTransactionHeaderFor::SuspendReplyDoneResponse(const ::fidl::DecodedMessage<MockDeviceThread::SuspendReplyDoneResponse>& _msg) {
+  fidl_init_txn_header(&_msg.message()->_hdr, 0, kMockDeviceThread_SuspendReplyDone_GenOrdinal);
+  _msg.message()->_hdr.flags[0] |= FIDL_TXN_HEADER_UNION_FROM_XUNION_FLAG;
+}
+
 namespace {
 
 [[maybe_unused]]
@@ -419,6 +481,12 @@
 constexpr uint64_t kMockDevice_UnbindReplyDone_GenOrdinal = 0x6f057a72a4b6c2e8lu;
 extern "C" const fidl_type_t v1_fuchsia_device_mock_MockDeviceUnbindReplyDoneRequestTable;
 extern "C" const fidl_type_t v1_fuchsia_device_mock_MockDeviceUnbindReplyDoneResponseTable;
+[[maybe_unused]]
+constexpr uint64_t kMockDevice_SuspendReplyDone_Ordinal = 0x2786b91000000000lu;
+[[maybe_unused]]
+constexpr uint64_t kMockDevice_SuspendReplyDone_GenOrdinal = 0x457f0f17b95a8de1lu;
+extern "C" const fidl_type_t v1_fuchsia_device_mock_MockDeviceSuspendReplyDoneRequestTable;
+extern "C" const fidl_type_t v1_fuchsia_device_mock_MockDeviceSuspendReplyDoneResponseTable;
 
 }  // namespace
 template <>
@@ -1000,7 +1068,7 @@
 }
 
 template <>
-MockDevice::ResultOf::Suspend_Impl<MockDevice::SuspendResponse>::Suspend_Impl(::zx::unowned_channel _client_end, ::llcpp::fuchsia::device::mock::HookInvocation record, uint32_t flags) {
+MockDevice::ResultOf::Suspend_Impl<MockDevice::SuspendResponse>::Suspend_Impl(::zx::unowned_channel _client_end, ::llcpp::fuchsia::device::mock::HookInvocation record, uint8_t requested_state, bool enable_wake, uint8_t suspend_reason) {
   constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<SuspendRequest, ::fidl::MessageDirection::kSending>();
   ::fidl::internal::AlignedBuffer<_kWriteAllocSize> _write_bytes_inlined;
   auto& _write_bytes_array = _write_bytes_inlined;
@@ -1008,23 +1076,25 @@
   memset(_write_bytes, 0, SuspendRequest::PrimarySize);
   auto& _request = *reinterpret_cast<SuspendRequest*>(_write_bytes);
   _request.record = std::move(record);
-  _request.flags = std::move(flags);
+  _request.requested_state = std::move(requested_state);
+  _request.enable_wake = std::move(enable_wake);
+  _request.suspend_reason = std::move(suspend_reason);
   ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(SuspendRequest));
   ::fidl::DecodedMessage<SuspendRequest> _decoded_request(std::move(_request_bytes));
   Super::SetResult(
       MockDevice::InPlace::Suspend(std::move(_client_end), std::move(_decoded_request), Super::response_buffer()));
 }
 
-MockDevice::ResultOf::Suspend MockDevice::SyncClient::Suspend(::llcpp::fuchsia::device::mock::HookInvocation record, uint32_t flags) {
-    return ResultOf::Suspend(::zx::unowned_channel(this->channel_), std::move(record), std::move(flags));
+MockDevice::ResultOf::Suspend MockDevice::SyncClient::Suspend(::llcpp::fuchsia::device::mock::HookInvocation record, uint8_t requested_state, bool enable_wake, uint8_t suspend_reason) {
+    return ResultOf::Suspend(::zx::unowned_channel(this->channel_), std::move(record), std::move(requested_state), std::move(enable_wake), std::move(suspend_reason));
 }
 
-MockDevice::ResultOf::Suspend MockDevice::Call::Suspend(::zx::unowned_channel _client_end, ::llcpp::fuchsia::device::mock::HookInvocation record, uint32_t flags) {
-  return ResultOf::Suspend(std::move(_client_end), std::move(record), std::move(flags));
+MockDevice::ResultOf::Suspend MockDevice::Call::Suspend(::zx::unowned_channel _client_end, ::llcpp::fuchsia::device::mock::HookInvocation record, uint8_t requested_state, bool enable_wake, uint8_t suspend_reason) {
+  return ResultOf::Suspend(std::move(_client_end), std::move(record), std::move(requested_state), std::move(enable_wake), std::move(suspend_reason));
 }
 
 template <>
-MockDevice::UnownedResultOf::Suspend_Impl<MockDevice::SuspendResponse>::Suspend_Impl(::zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::llcpp::fuchsia::device::mock::HookInvocation record, uint32_t flags, ::fidl::BytePart _response_buffer) {
+MockDevice::UnownedResultOf::Suspend_Impl<MockDevice::SuspendResponse>::Suspend_Impl(::zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::llcpp::fuchsia::device::mock::HookInvocation record, uint8_t requested_state, bool enable_wake, uint8_t suspend_reason, ::fidl::BytePart _response_buffer) {
   if (_request_buffer.capacity() < SuspendRequest::PrimarySize) {
     Super::SetFailure(::fidl::DecodeResult<SuspendResponse>(ZX_ERR_BUFFER_TOO_SMALL, ::fidl::internal::kErrorRequestBufferTooSmall));
     return;
@@ -1032,19 +1102,21 @@
   memset(_request_buffer.data(), 0, SuspendRequest::PrimarySize);
   auto& _request = *reinterpret_cast<SuspendRequest*>(_request_buffer.data());
   _request.record = std::move(record);
-  _request.flags = std::move(flags);
+  _request.requested_state = std::move(requested_state);
+  _request.enable_wake = std::move(enable_wake);
+  _request.suspend_reason = std::move(suspend_reason);
   _request_buffer.set_actual(sizeof(SuspendRequest));
   ::fidl::DecodedMessage<SuspendRequest> _decoded_request(std::move(_request_buffer));
   Super::SetResult(
       MockDevice::InPlace::Suspend(std::move(_client_end), std::move(_decoded_request), std::move(_response_buffer)));
 }
 
-MockDevice::UnownedResultOf::Suspend MockDevice::SyncClient::Suspend(::fidl::BytePart _request_buffer, ::llcpp::fuchsia::device::mock::HookInvocation record, uint32_t flags, ::fidl::BytePart _response_buffer) {
-  return UnownedResultOf::Suspend(::zx::unowned_channel(this->channel_), std::move(_request_buffer), std::move(record), std::move(flags), std::move(_response_buffer));
+MockDevice::UnownedResultOf::Suspend MockDevice::SyncClient::Suspend(::fidl::BytePart _request_buffer, ::llcpp::fuchsia::device::mock::HookInvocation record, uint8_t requested_state, bool enable_wake, uint8_t suspend_reason, ::fidl::BytePart _response_buffer) {
+  return UnownedResultOf::Suspend(::zx::unowned_channel(this->channel_), std::move(_request_buffer), std::move(record), std::move(requested_state), std::move(enable_wake), std::move(suspend_reason), std::move(_response_buffer));
 }
 
-MockDevice::UnownedResultOf::Suspend MockDevice::Call::Suspend(::zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::llcpp::fuchsia::device::mock::HookInvocation record, uint32_t flags, ::fidl::BytePart _response_buffer) {
-  return UnownedResultOf::Suspend(std::move(_client_end), std::move(_request_buffer), std::move(record), std::move(flags), std::move(_response_buffer));
+MockDevice::UnownedResultOf::Suspend MockDevice::Call::Suspend(::zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::llcpp::fuchsia::device::mock::HookInvocation record, uint8_t requested_state, bool enable_wake, uint8_t suspend_reason, ::fidl::BytePart _response_buffer) {
+  return UnownedResultOf::Suspend(std::move(_client_end), std::move(_request_buffer), std::move(record), std::move(requested_state), std::move(enable_wake), std::move(suspend_reason), std::move(_response_buffer));
 }
 
 ::fidl::DecodeResult<MockDevice::SuspendResponse> MockDevice::InPlace::Suspend(::zx::unowned_channel _client_end, ::fidl::DecodedMessage<SuspendRequest> params, ::fidl::BytePart response_buffer) {
@@ -1378,6 +1450,69 @@
 }
 
 
+MockDevice::ResultOf::SuspendReplyDone_Impl::SuspendReplyDone_Impl(::zx::unowned_channel _client_end, uint64_t action_id) {
+  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<SuspendReplyDoneRequest, ::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, SuspendReplyDoneRequest::PrimarySize);
+  auto& _request = *reinterpret_cast<SuspendReplyDoneRequest*>(_write_bytes);
+  _request.action_id = std::move(action_id);
+  ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(SuspendReplyDoneRequest));
+  ::fidl::DecodedMessage<SuspendReplyDoneRequest> _decoded_request(std::move(_request_bytes));
+  Super::operator=(
+      MockDevice::InPlace::SuspendReplyDone(std::move(_client_end), std::move(_decoded_request)));
+}
+
+MockDevice::ResultOf::SuspendReplyDone MockDevice::SyncClient::SuspendReplyDone(uint64_t action_id) {
+    return ResultOf::SuspendReplyDone(::zx::unowned_channel(this->channel_), std::move(action_id));
+}
+
+MockDevice::ResultOf::SuspendReplyDone MockDevice::Call::SuspendReplyDone(::zx::unowned_channel _client_end, uint64_t action_id) {
+  return ResultOf::SuspendReplyDone(std::move(_client_end), std::move(action_id));
+}
+
+
+MockDevice::UnownedResultOf::SuspendReplyDone_Impl::SuspendReplyDone_Impl(::zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, uint64_t action_id) {
+  if (_request_buffer.capacity() < SuspendReplyDoneRequest::PrimarySize) {
+    Super::status_ = ZX_ERR_BUFFER_TOO_SMALL;
+    Super::error_ = ::fidl::internal::kErrorRequestBufferTooSmall;
+    return;
+  }
+  memset(_request_buffer.data(), 0, SuspendReplyDoneRequest::PrimarySize);
+  auto& _request = *reinterpret_cast<SuspendReplyDoneRequest*>(_request_buffer.data());
+  _request.action_id = std::move(action_id);
+  _request_buffer.set_actual(sizeof(SuspendReplyDoneRequest));
+  ::fidl::DecodedMessage<SuspendReplyDoneRequest> _decoded_request(std::move(_request_buffer));
+  Super::operator=(
+      MockDevice::InPlace::SuspendReplyDone(std::move(_client_end), std::move(_decoded_request)));
+}
+
+MockDevice::UnownedResultOf::SuspendReplyDone MockDevice::SyncClient::SuspendReplyDone(::fidl::BytePart _request_buffer, uint64_t action_id) {
+  return UnownedResultOf::SuspendReplyDone(::zx::unowned_channel(this->channel_), std::move(_request_buffer), std::move(action_id));
+}
+
+MockDevice::UnownedResultOf::SuspendReplyDone MockDevice::Call::SuspendReplyDone(::zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, uint64_t action_id) {
+  return UnownedResultOf::SuspendReplyDone(std::move(_client_end), std::move(_request_buffer), std::move(action_id));
+}
+
+::fidl::internal::StatusAndError MockDevice::InPlace::SuspendReplyDone(::zx::unowned_channel _client_end, ::fidl::DecodedMessage<SuspendReplyDoneRequest> params) {
+  MockDevice::SetTransactionHeaderFor::SuspendReplyDoneRequest(params);
+  auto _encode_request_result = ::fidl::Encode(std::move(params));
+  if (_encode_request_result.status != ZX_OK) {
+    return ::fidl::internal::StatusAndError::FromFailure(
+        std::move(_encode_request_result));
+  }
+  zx_status_t _write_status =
+      ::fidl::Write(std::move(_client_end), std::move(_encode_request_result.message));
+  if (_write_status != ZX_OK) {
+    return ::fidl::internal::StatusAndError(_write_status, ::fidl::internal::kErrorWriteFailed);
+  } else {
+    return ::fidl::internal::StatusAndError(ZX_OK, nullptr);
+  }
+}
+
+
 bool MockDevice::TryDispatch(Interface* impl, fidl_msg_t* msg, ::fidl::Transaction* txn) {
   if (msg->num_bytes < sizeof(fidl_message_header_t)) {
     zx_handle_close_many(msg->handles, msg->num_handles);
@@ -1517,7 +1652,7 @@
         return true;
       }
       auto message = result.message.message();
-      impl->Suspend(std::move(message->record), std::move(message->flags),
+      impl->Suspend(std::move(message->record), std::move(message->requested_state), std::move(message->enable_wake), std::move(message->suspend_reason),
           Interface::SuspendCompleter::Sync(txn));
       return true;
     }
@@ -1586,6 +1721,19 @@
           Interface::UnbindReplyDoneCompleter::Sync(txn));
       return true;
     }
+    case kMockDevice_SuspendReplyDone_Ordinal:
+    case kMockDevice_SuspendReplyDone_GenOrdinal:
+    {
+      auto result = ::fidl::DecodeAs<SuspendReplyDoneRequest>(msg);
+      if (result.status != ZX_OK) {
+        txn->Close(ZX_ERR_INVALID_ARGS);
+        return true;
+      }
+      auto message = result.message.message();
+      impl->SuspendReplyDone(std::move(message->action_id),
+          Interface::SuspendReplyDoneCompleter::Sync(txn));
+      return true;
+    }
     default: {
       return false;
     }
@@ -2278,6 +2426,11 @@
   _msg.message()->_hdr.flags[0] |= FIDL_TXN_HEADER_UNION_FROM_XUNION_FLAG;
 }
 
+void MockDevice::SetTransactionHeaderFor::SuspendReplyDoneRequest(const ::fidl::DecodedMessage<MockDevice::SuspendReplyDoneRequest>& _msg) {
+  fidl_init_txn_header(&_msg.message()->_hdr, 0, kMockDevice_SuspendReplyDone_GenOrdinal);
+  _msg.message()->_hdr.flags[0] |= FIDL_TXN_HEADER_UNION_FROM_XUNION_FLAG;
+}
+
 }  // namespace mock
 }  // namespace device
 }  // namespace fuchsia
diff --git a/zircon/system/dev/test/mock-device/gen/llcpp/include/fuchsia/device/mock/llcpp/fidl.h b/zircon/system/dev/test/mock-device/gen/llcpp/include/fuchsia/device/mock/llcpp/fidl.h
index d0d7cce..70ab31b 100644
--- a/zircon/system/dev/test/mock-device/gen/llcpp/include/fuchsia/device/mock/llcpp/fidl.h
+++ b/zircon/system/dev/test/mock-device/gen/llcpp/include/fuchsia/device/mock/llcpp/fidl.h
@@ -26,6 +26,7 @@
 struct AddDeviceAction;
 struct HookInvocation;
 struct UnbindReplyAction;
+struct SuspendReplyAction;
 struct Action;
 class MockDeviceThread;
 class MockDevice;
@@ -43,6 +44,7 @@
     kAsyncRemoveDevice = 4,  // 0x4
     kUnbindReply = 5,  // 0x5
     kAddDevice = 6,  // 0x6
+    kSuspendReply = 7,  // 0x7
   };
 
   bool has_invalid_tag() const { return ordinal_ == Ordinal::Invalid; }
@@ -190,6 +192,30 @@
     ZX_ASSERT(ordinal() == Ordinal::kAddDevice);
     return *static_cast<::llcpp::fuchsia::device::mock::AddDeviceAction*>(envelope_.data);
   }
+
+  bool is_suspend_reply() const { return ordinal() == Ordinal::kSuspendReply; }
+
+  static Action WithSuspendReply(::llcpp::fuchsia::device::mock::SuspendReplyAction* val) {
+    Action result;
+    result.set_suspend_reply(val);
+    return result;
+  }
+
+  // Signal that the suspend has completed.
+  void set_suspend_reply(::llcpp::fuchsia::device::mock::SuspendReplyAction* elem) {
+    ordinal_ = Ordinal::kSuspendReply;
+    envelope_.data = static_cast<void*>(elem);
+  }
+
+  // Signal that the suspend has completed.
+  ::llcpp::fuchsia::device::mock::SuspendReplyAction& mutable_suspend_reply() {
+    ZX_ASSERT(ordinal() == Ordinal::kSuspendReply);
+    return *static_cast<::llcpp::fuchsia::device::mock::SuspendReplyAction*>(envelope_.data);
+  }
+  const ::llcpp::fuchsia::device::mock::SuspendReplyAction& suspend_reply() const {
+    ZX_ASSERT(ordinal() == Ordinal::kSuspendReply);
+    return *static_cast<::llcpp::fuchsia::device::mock::SuspendReplyAction*>(envelope_.data);
+  }
   Tag which() const {
     ZX_ASSERT(!has_invalid_tag());
     return static_cast<Tag>(ordinal());
@@ -211,6 +237,7 @@
     kAsyncRemoveDevice = 4,  // 0x4
     kUnbindReply = 5,  // 0x5
     kAddDevice = 6,  // 0x6
+    kSuspendReply = 7,  // 0x7
   };
 
   Ordinal ordinal() const {
@@ -291,12 +318,29 @@
   uint64_t action_id = {};
 };
 
+extern "C" const fidl_type_t v1_fuchsia_device_mock_SuspendReplyActionTable;
+
+// Marker struct for suspend reply action
+struct SuspendReplyAction {
+  static constexpr const fidl_type_t* Type = &v1_fuchsia_device_mock_SuspendReplyActionTable;
+  static constexpr uint32_t MaxNumHandles = 0;
+  static constexpr uint32_t PrimarySize = 8;
+  [[maybe_unused]]
+  static constexpr uint32_t MaxOutOfLine = 0;
+  static constexpr bool HasPointer = false;
+
+  // Value that will be echoed back in the completion message
+  uint64_t action_id = {};
+};
+
 extern "C" const fidl_type_t v1_fuchsia_device_mock_MockDeviceThreadPerformActionsRequestTable;
 extern "C" const fidl_type_t v1_fuchsia_device_mock_MockDeviceThreadPerformActionsResponseTable;
 extern "C" const fidl_type_t v1_fuchsia_device_mock_MockDeviceThreadAddDeviceDoneRequestTable;
 extern "C" const fidl_type_t v1_fuchsia_device_mock_MockDeviceThreadAddDeviceDoneEventTable;
 extern "C" const fidl_type_t v1_fuchsia_device_mock_MockDeviceThreadUnbindReplyDoneRequestTable;
 extern "C" const fidl_type_t v1_fuchsia_device_mock_MockDeviceThreadUnbindReplyDoneEventTable;
+extern "C" const fidl_type_t v1_fuchsia_device_mock_MockDeviceThreadSuspendReplyDoneRequestTable;
+extern "C" const fidl_type_t v1_fuchsia_device_mock_MockDeviceThreadSuspendReplyDoneEventTable;
 
 // Interface for requesting a mock device thread do something.  The mock device implements
 // this interface.  Closing the interface causes the thread to exit.
@@ -352,6 +396,21 @@
     static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
         ::fidl::internal::TransactionalMessageKind::kResponse;
   };
+  struct SuspendReplyDoneResponse final {
+    FIDL_ALIGNDECL
+    fidl_message_header_t _hdr;
+    uint64_t action_id;
+
+    static constexpr const fidl_type_t* Type = &v1_fuchsia_device_mock_MockDeviceThreadSuspendReplyDoneEventTable;
+    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 bool HasPointer = false;
+    static constexpr bool ContainsUnion = false;
+    static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
+        ::fidl::internal::TransactionalMessageKind::kResponse;
+  };
 
   struct EventHandlers {
     // Notification that the requested action was done
@@ -359,6 +418,8 @@
 
     fit::callback<zx_status_t(uint64_t action_id)> unbind_reply_done;
 
+    fit::callback<zx_status_t(uint64_t action_id)> suspend_reply_done;
+
     // Fallback handler when an unknown ordinal is received.
     // Caller may put custom error handling logic here.
     fit::callback<zx_status_t()> unknown;
@@ -515,6 +576,14 @@
   // Messages are encoded in-place.
   static zx_status_t SendUnbindReplyDoneEvent(::zx::unowned_channel _chan, ::fidl::DecodedMessage<UnbindReplyDoneResponse> params);
 
+  static zx_status_t SendSuspendReplyDoneEvent(::zx::unowned_channel _chan, uint64_t action_id);
+
+  // Caller provides the backing storage for FIDL message via response buffers.
+  static zx_status_t SendSuspendReplyDoneEvent(::zx::unowned_channel _chan, ::fidl::BytePart _buffer, uint64_t action_id);
+
+  // Messages are encoded in-place.
+  static zx_status_t SendSuspendReplyDoneEvent(::zx::unowned_channel _chan, ::fidl::DecodedMessage<SuspendReplyDoneResponse> params);
+
 
   // Helper functions to fill in the transaction header in a |DecodedMessage<TransactionalMessage>|.
   class SetTransactionHeaderFor final {
@@ -523,6 +592,7 @@
     static void PerformActionsRequest(const ::fidl::DecodedMessage<MockDeviceThread::PerformActionsRequest>& _msg);
     static void AddDeviceDoneResponse(const ::fidl::DecodedMessage<MockDeviceThread::AddDeviceDoneResponse>& _msg);
     static void UnbindReplyDoneResponse(const ::fidl::DecodedMessage<MockDeviceThread::UnbindReplyDoneResponse>& _msg);
+    static void SuspendReplyDoneResponse(const ::fidl::DecodedMessage<MockDeviceThread::SuspendReplyDoneResponse>& _msg);
   };
 };
 
@@ -556,6 +626,8 @@
 extern "C" const fidl_type_t v1_fuchsia_device_mock_MockDeviceAddDeviceDoneResponseTable;
 extern "C" const fidl_type_t v1_fuchsia_device_mock_MockDeviceUnbindReplyDoneRequestTable;
 extern "C" const fidl_type_t v1_fuchsia_device_mock_MockDeviceUnbindReplyDoneResponseTable;
+extern "C" const fidl_type_t v1_fuchsia_device_mock_MockDeviceSuspendReplyDoneRequestTable;
+extern "C" const fidl_type_t v1_fuchsia_device_mock_MockDeviceSuspendReplyDoneResponseTable;
 
 // Interface for controlling a mock device.  The test suite will implement this interface.
 // Any method that returns a list of actions is interpreted as requesting the corresponding hook
@@ -880,7 +952,9 @@
     FIDL_ALIGNDECL
     fidl_message_header_t _hdr;
     ::llcpp::fuchsia::device::mock::HookInvocation record;
-    uint32_t flags;
+    uint8_t requested_state;
+    bool enable_wake;
+    uint8_t suspend_reason;
 
     static constexpr const fidl_type_t* Type = &v1_fuchsia_device_mock_MockDeviceSuspendRequestTable;
     static constexpr uint32_t MaxNumHandles = 0;
@@ -1035,6 +1109,24 @@
         ::fidl::internal::TransactionalMessageKind::kRequest;
   };
 
+  struct SuspendReplyDoneRequest final {
+    FIDL_ALIGNDECL
+    fidl_message_header_t _hdr;
+    uint64_t action_id;
+
+    static constexpr const fidl_type_t* Type = &v1_fuchsia_device_mock_MockDeviceSuspendReplyDoneRequestTable;
+    static constexpr uint32_t MaxNumHandles = 0;
+    static constexpr uint32_t PrimarySize = 24;
+    static constexpr uint32_t MaxOutOfLine = 0;
+    static constexpr uint32_t AltPrimarySize = 24;
+    static constexpr uint32_t AltMaxOutOfLine = 0;
+    static constexpr bool HasFlexibleEnvelope = false;
+    static constexpr bool HasPointer = false;
+    static constexpr bool ContainsUnion = false;
+    static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
+        ::fidl::internal::TransactionalMessageKind::kRequest;
+  };
+
 
   // Collection of return types of FIDL calls in this interface.
   class ResultOf final {
@@ -1183,7 +1275,7 @@
     class Suspend_Impl final : private ::fidl::internal::OwnedSyncCallBase<ResponseType> {
       using Super = ::fidl::internal::OwnedSyncCallBase<ResponseType>;
      public:
-      Suspend_Impl(::zx::unowned_channel _client_end, ::llcpp::fuchsia::device::mock::HookInvocation record, uint32_t flags);
+      Suspend_Impl(::zx::unowned_channel _client_end, ::llcpp::fuchsia::device::mock::HookInvocation record, uint8_t requested_state, bool enable_wake, uint8_t suspend_reason);
       ~Suspend_Impl() = default;
       Suspend_Impl(Suspend_Impl&& other) = default;
       Suspend_Impl& operator=(Suspend_Impl&& other) = default;
@@ -1265,6 +1357,17 @@
       using Super::error;
       using Super::ok;
     };
+    class SuspendReplyDone_Impl final : private ::fidl::internal::StatusAndError {
+      using Super = ::fidl::internal::StatusAndError;
+     public:
+      SuspendReplyDone_Impl(::zx::unowned_channel _client_end, uint64_t action_id);
+      ~SuspendReplyDone_Impl() = default;
+      SuspendReplyDone_Impl(SuspendReplyDone_Impl&& other) = default;
+      SuspendReplyDone_Impl& operator=(SuspendReplyDone_Impl&& other) = default;
+      using Super::status;
+      using Super::error;
+      using Super::ok;
+    };
 
    public:
     using Bind = Bind_Impl<BindResponse>;
@@ -1282,6 +1385,7 @@
     using Rxrpc = Rxrpc_Impl<RxrpcResponse>;
     using AddDeviceDone = AddDeviceDone_Impl;
     using UnbindReplyDone = UnbindReplyDone_Impl;
+    using SuspendReplyDone = SuspendReplyDone_Impl;
   };
 
   // Collection of return types of FIDL calls in this interface,
@@ -1432,7 +1536,7 @@
     class Suspend_Impl final : private ::fidl::internal::UnownedSyncCallBase<ResponseType> {
       using Super = ::fidl::internal::UnownedSyncCallBase<ResponseType>;
      public:
-      Suspend_Impl(::zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::llcpp::fuchsia::device::mock::HookInvocation record, uint32_t flags, ::fidl::BytePart _response_buffer);
+      Suspend_Impl(::zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::llcpp::fuchsia::device::mock::HookInvocation record, uint8_t requested_state, bool enable_wake, uint8_t suspend_reason, ::fidl::BytePart _response_buffer);
       ~Suspend_Impl() = default;
       Suspend_Impl(Suspend_Impl&& other) = default;
       Suspend_Impl& operator=(Suspend_Impl&& other) = default;
@@ -1514,6 +1618,17 @@
       using Super::error;
       using Super::ok;
     };
+    class SuspendReplyDone_Impl final : private ::fidl::internal::StatusAndError {
+      using Super = ::fidl::internal::StatusAndError;
+     public:
+      SuspendReplyDone_Impl(::zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, uint64_t action_id);
+      ~SuspendReplyDone_Impl() = default;
+      SuspendReplyDone_Impl(SuspendReplyDone_Impl&& other) = default;
+      SuspendReplyDone_Impl& operator=(SuspendReplyDone_Impl&& other) = default;
+      using Super::status;
+      using Super::error;
+      using Super::ok;
+    };
 
    public:
     using Bind = Bind_Impl<BindResponse>;
@@ -1531,6 +1646,7 @@
     using Rxrpc = Rxrpc_Impl<RxrpcResponse>;
     using AddDeviceDone = AddDeviceDone_Impl;
     using UnbindReplyDone = UnbindReplyDone_Impl;
+    using SuspendReplyDone = SuspendReplyDone_Impl;
   };
 
   class SyncClient final {
@@ -1601,10 +1717,10 @@
     UnownedResultOf::GetSize GetSize(::fidl::BytePart _request_buffer, ::llcpp::fuchsia::device::mock::HookInvocation record, ::fidl::BytePart _response_buffer);
 
     // Allocates 48 bytes of request buffer on the stack. Response is heap-allocated.
-    ResultOf::Suspend Suspend(::llcpp::fuchsia::device::mock::HookInvocation record, uint32_t flags);
+    ResultOf::Suspend Suspend(::llcpp::fuchsia::device::mock::HookInvocation record, uint8_t requested_state, bool enable_wake, uint8_t suspend_reason);
 
     // Caller provides the backing storage for FIDL message via request and response buffers.
-    UnownedResultOf::Suspend Suspend(::fidl::BytePart _request_buffer, ::llcpp::fuchsia::device::mock::HookInvocation record, uint32_t flags, ::fidl::BytePart _response_buffer);
+    UnownedResultOf::Suspend Suspend(::fidl::BytePart _request_buffer, ::llcpp::fuchsia::device::mock::HookInvocation record, uint8_t requested_state, bool enable_wake, uint8_t suspend_reason, ::fidl::BytePart _response_buffer);
 
     // Allocates 48 bytes of request buffer on the stack. Response is heap-allocated.
     ResultOf::Resume Resume(::llcpp::fuchsia::device::mock::HookInvocation record, uint32_t flags);
@@ -1638,6 +1754,12 @@
     // Caller provides the backing storage for FIDL message via request and response buffers.
     UnownedResultOf::UnbindReplyDone UnbindReplyDone(::fidl::BytePart _request_buffer, uint64_t action_id);
 
+    // Allocates 24 bytes of message buffer on the stack. No heap allocation necessary.
+    ResultOf::SuspendReplyDone SuspendReplyDone(uint64_t action_id);
+
+    // Caller provides the backing storage for FIDL message via request and response buffers.
+    UnownedResultOf::SuspendReplyDone SuspendReplyDone(::fidl::BytePart _request_buffer, uint64_t action_id);
+
    private:
     ::zx::channel channel_;
   };
@@ -1704,10 +1826,10 @@
     static UnownedResultOf::GetSize GetSize(::zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::llcpp::fuchsia::device::mock::HookInvocation record, ::fidl::BytePart _response_buffer);
 
     // Allocates 48 bytes of request buffer on the stack. Response is heap-allocated.
-    static ResultOf::Suspend Suspend(::zx::unowned_channel _client_end, ::llcpp::fuchsia::device::mock::HookInvocation record, uint32_t flags);
+    static ResultOf::Suspend Suspend(::zx::unowned_channel _client_end, ::llcpp::fuchsia::device::mock::HookInvocation record, uint8_t requested_state, bool enable_wake, uint8_t suspend_reason);
 
     // 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, ::llcpp::fuchsia::device::mock::HookInvocation record, uint32_t flags, ::fidl::BytePart _response_buffer);
+    static UnownedResultOf::Suspend Suspend(::zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, ::llcpp::fuchsia::device::mock::HookInvocation record, uint8_t requested_state, bool enable_wake, uint8_t suspend_reason, ::fidl::BytePart _response_buffer);
 
     // Allocates 48 bytes of request buffer on the stack. Response is heap-allocated.
     static ResultOf::Resume Resume(::zx::unowned_channel _client_end, ::llcpp::fuchsia::device::mock::HookInvocation record, uint32_t flags);
@@ -1741,6 +1863,12 @@
     // Caller provides the backing storage for FIDL message via request and response buffers.
     static UnownedResultOf::UnbindReplyDone UnbindReplyDone(::zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, uint64_t action_id);
 
+    // Allocates 24 bytes of message buffer on the stack. No heap allocation necessary.
+    static ResultOf::SuspendReplyDone SuspendReplyDone(::zx::unowned_channel _client_end, uint64_t action_id);
+
+    // Caller provides the backing storage for FIDL message via request and response buffers.
+    static UnownedResultOf::SuspendReplyDone SuspendReplyDone(::zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, uint64_t action_id);
+
   };
 
   // Messages are encoded and decoded in-place when these methods are used.
@@ -1781,6 +1909,8 @@
 
     static ::fidl::internal::StatusAndError UnbindReplyDone(::zx::unowned_channel _client_end, ::fidl::DecodedMessage<UnbindReplyDoneRequest> params);
 
+    static ::fidl::internal::StatusAndError SuspendReplyDone(::zx::unowned_channel _client_end, ::fidl::DecodedMessage<SuspendReplyDoneRequest> params);
+
   };
 
   // Pure-virtual interface to be implemented by a server.
@@ -1919,7 +2049,7 @@
 
     using SuspendCompleter = ::fidl::Completer<SuspendCompleterBase>;
 
-    virtual void Suspend(::llcpp::fuchsia::device::mock::HookInvocation record, uint32_t flags, SuspendCompleter::Sync _completer) = 0;
+    virtual void Suspend(::llcpp::fuchsia::device::mock::HookInvocation record, uint8_t requested_state, bool enable_wake, uint8_t suspend_reason, SuspendCompleter::Sync _completer) = 0;
 
     class ResumeCompleterBase : public _Base {
      public:
@@ -1971,6 +2101,10 @@
 
     virtual void UnbindReplyDone(uint64_t action_id, UnbindReplyDoneCompleter::Sync _completer) = 0;
 
+    using SuspendReplyDoneCompleter = ::fidl::Completer<>;
+
+    virtual void SuspendReplyDone(uint64_t action_id, SuspendReplyDoneCompleter::Sync _completer) = 0;
+
   };
 
   // Attempts to dispatch the incoming message to a handler function in the server implementation.
@@ -2023,6 +2157,7 @@
     static void RxrpcResponse(const ::fidl::DecodedMessage<MockDevice::RxrpcResponse>& _msg);
     static void AddDeviceDoneRequest(const ::fidl::DecodedMessage<MockDevice::AddDeviceDoneRequest>& _msg);
     static void UnbindReplyDoneRequest(const ::fidl::DecodedMessage<MockDevice::UnbindReplyDoneRequest>& _msg);
+    static void SuspendReplyDoneRequest(const ::fidl::DecodedMessage<MockDevice::SuspendReplyDoneRequest>& _msg);
   };
 };
 
@@ -2067,6 +2202,12 @@
 static_assert(sizeof(::llcpp::fuchsia::device::mock::UnbindReplyAction) == ::llcpp::fuchsia::device::mock::UnbindReplyAction::PrimarySize);
 
 template <>
+struct IsFidlType<::llcpp::fuchsia::device::mock::SuspendReplyAction> : public std::true_type {};
+static_assert(std::is_standard_layout_v<::llcpp::fuchsia::device::mock::SuspendReplyAction>);
+static_assert(offsetof(::llcpp::fuchsia::device::mock::SuspendReplyAction, action_id) == 0);
+static_assert(sizeof(::llcpp::fuchsia::device::mock::SuspendReplyAction) == ::llcpp::fuchsia::device::mock::SuspendReplyAction::PrimarySize);
+
+template <>
 struct IsFidlType<::llcpp::fuchsia::device::mock::Action> : public std::true_type {};
 static_assert(std::is_standard_layout_v<::llcpp::fuchsia::device::mock::Action>);
 
@@ -2095,6 +2236,14 @@
 static_assert(offsetof(::llcpp::fuchsia::device::mock::MockDeviceThread::UnbindReplyDoneResponse, action_id) == 16);
 
 template <>
+struct IsFidlType<::llcpp::fuchsia::device::mock::MockDeviceThread::SuspendReplyDoneResponse> : public std::true_type {};
+template <>
+struct IsFidlMessage<::llcpp::fuchsia::device::mock::MockDeviceThread::SuspendReplyDoneResponse> : public std::true_type {};
+static_assert(sizeof(::llcpp::fuchsia::device::mock::MockDeviceThread::SuspendReplyDoneResponse)
+    == ::llcpp::fuchsia::device::mock::MockDeviceThread::SuspendReplyDoneResponse::PrimarySize);
+static_assert(offsetof(::llcpp::fuchsia::device::mock::MockDeviceThread::SuspendReplyDoneResponse, action_id) == 16);
+
+template <>
 struct IsFidlType<::llcpp::fuchsia::device::mock::MockDevice::BindRequest> : public std::true_type {};
 template <>
 struct IsFidlMessage<::llcpp::fuchsia::device::mock::MockDevice::BindRequest> : public std::true_type {};
@@ -2244,7 +2393,9 @@
 static_assert(sizeof(::llcpp::fuchsia::device::mock::MockDevice::SuspendRequest)
     == ::llcpp::fuchsia::device::mock::MockDevice::SuspendRequest::PrimarySize);
 static_assert(offsetof(::llcpp::fuchsia::device::mock::MockDevice::SuspendRequest, record) == 16);
-static_assert(offsetof(::llcpp::fuchsia::device::mock::MockDevice::SuspendRequest, flags) == 40);
+static_assert(offsetof(::llcpp::fuchsia::device::mock::MockDevice::SuspendRequest, requested_state) == 40);
+static_assert(offsetof(::llcpp::fuchsia::device::mock::MockDevice::SuspendRequest, enable_wake) == 41);
+static_assert(offsetof(::llcpp::fuchsia::device::mock::MockDevice::SuspendRequest, suspend_reason) == 42);
 
 template <>
 struct IsFidlType<::llcpp::fuchsia::device::mock::MockDevice::SuspendResponse> : public std::true_type {};
@@ -2319,4 +2470,12 @@
     == ::llcpp::fuchsia::device::mock::MockDevice::UnbindReplyDoneRequest::PrimarySize);
 static_assert(offsetof(::llcpp::fuchsia::device::mock::MockDevice::UnbindReplyDoneRequest, action_id) == 16);
 
+template <>
+struct IsFidlType<::llcpp::fuchsia::device::mock::MockDevice::SuspendReplyDoneRequest> : public std::true_type {};
+template <>
+struct IsFidlMessage<::llcpp::fuchsia::device::mock::MockDevice::SuspendReplyDoneRequest> : public std::true_type {};
+static_assert(sizeof(::llcpp::fuchsia::device::mock::MockDevice::SuspendReplyDoneRequest)
+    == ::llcpp::fuchsia::device::mock::MockDevice::SuspendReplyDoneRequest::PrimarySize);
+static_assert(offsetof(::llcpp::fuchsia::device::mock::MockDevice::SuspendReplyDoneRequest, action_id) == 16);
+
 }  // namespace fidl
diff --git a/zircon/system/dev/test/mock-device/mock-device.fidl b/zircon/system/dev/test/mock-device/mock-device.fidl
index d166ca8..4edb879 100644
--- a/zircon/system/dev/test/mock-device/mock-device.fidl
+++ b/zircon/system/dev/test/mock-device/mock-device.fidl
@@ -22,6 +22,12 @@
     uint64 action_id;
 };
 
+/// Marker struct for suspend reply action
+struct SuspendReplyAction {
+    /// Value that will be echoed back in the completion message
+    uint64 action_id;
+};
+
 const uint32 MAX_PROPERTIES_LEN = 32;
 const uint32 MAX_NAME_LEN = 32;
 
@@ -67,6 +73,9 @@
 
     /// Create a new child device
     6: AddDeviceAction add_device;
+
+    /// Signal that the suspend has completed.
+    7: SuspendReplyAction suspend_reply;
 };
 
 const uint32 MAX_ACTIONS = 10;
@@ -87,7 +96,7 @@
     Read(HookInvocation record, uint64 count, zx.off off) -> (vector<Action>:MAX_ACTIONS actions);
     Write(HookInvocation record, vector<uint8>:MAX_WRITE_BYTES buffer, zx.off off) -> (vector<Action>:MAX_ACTIONS actions);
     GetSize(HookInvocation record) -> (vector<Action>:MAX_ACTIONS actions);
-    Suspend(HookInvocation record, uint32 flags) -> (vector<Action>:MAX_ACTIONS actions);
+    Suspend(HookInvocation record, uint8 requested_state, bool enable_wake, uint8 suspend_reason) -> (vector<Action>:MAX_ACTIONS actions);
     Resume(HookInvocation record, uint32 flags) -> (vector<Action>:MAX_ACTIONS actions);
 
     Message(HookInvocation record) -> (vector<Action>:MAX_ACTIONS actions);
@@ -96,6 +105,7 @@
     /// Notification that the requested action was done
     AddDeviceDone(uint64 action_id);
     UnbindReplyDone(uint64 action_id);
+    SuspendReplyDone(uint64 action_id);
 };
 
 /// Interface for requesting a mock device thread do something.  The mock device implements
@@ -107,4 +117,5 @@
     /// Notification that the requested action was done
     -> AddDeviceDone(uint64 action_id);
     -> UnbindReplyDone(uint64 action_id);
+    -> SuspendReplyDone(uint64 action_id);
 };
diff --git a/zircon/system/fidl/fuchsia-device/controller.fidl b/zircon/system/fidl/fuchsia-device/controller.fidl
index d0874db..0136431 100644
--- a/zircon/system/fidl/fuchsia-device/controller.fidl
+++ b/zircon/system/fidl/fuchsia-device/controller.fidl
@@ -156,8 +156,6 @@
     /// Each set bit in `set_flags` will then be set in the log flags state.
     SetDriverLogFlags(uint32 clear_flags, uint32 set_flags) -> (zx.status status);
 
-    /// Debug command: execute the device's suspend hook
-    DebugSuspend() -> (zx.status status);
     /// Debug command: execute the device's resume hook
     DebugResume() -> (zx.status status);
 
diff --git a/zircon/system/fidl/fuchsia-device/gen/llcpp/fidl.cc b/zircon/system/fidl/fuchsia-device/gen/llcpp/fidl.cc
index 20a3118..5bee540 100644
--- a/zircon/system/fidl/fuchsia-device/gen/llcpp/fidl.cc
+++ b/zircon/system/fidl/fuchsia-device/gen/llcpp/fidl.cc
@@ -303,12 +303,6 @@
 extern "C" const fidl_type_t v1_fuchsia_device_ControllerSetDriverLogFlagsRequestTable;
 extern "C" const fidl_type_t v1_fuchsia_device_ControllerSetDriverLogFlagsResponseTable;
 [[maybe_unused]]
-constexpr uint64_t kController_DebugSuspend_Ordinal = 0x65f2322400000000lu;
-[[maybe_unused]]
-constexpr uint64_t kController_DebugSuspend_GenOrdinal = 0x37827c5e2f45e12elu;
-extern "C" const fidl_type_t v1_fuchsia_device_ControllerDebugSuspendRequestTable;
-extern "C" const fidl_type_t v1_fuchsia_device_ControllerDebugSuspendResponseTable;
-[[maybe_unused]]
 constexpr uint64_t kController_DebugResume_Ordinal = 0x5fee29c400000000lu;
 [[maybe_unused]]
 constexpr uint64_t kController_DebugResume_GenOrdinal = 0xe1555cdd68b40e6lu;
@@ -935,67 +929,6 @@
 }
 
 template <>
-Controller::ResultOf::DebugSuspend_Impl<Controller::DebugSuspendResponse>::DebugSuspend_Impl(::zx::unowned_channel _client_end) {
-  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<DebugSuspendRequest, ::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, DebugSuspendRequest::PrimarySize);
-  ::fidl::BytePart _request_bytes(_write_bytes, _kWriteAllocSize, sizeof(DebugSuspendRequest));
-  ::fidl::DecodedMessage<DebugSuspendRequest> _decoded_request(std::move(_request_bytes));
-  Super::SetResult(
-      Controller::InPlace::DebugSuspend(std::move(_client_end), Super::response_buffer()));
-}
-
-Controller::ResultOf::DebugSuspend Controller::SyncClient::DebugSuspend() {
-    return ResultOf::DebugSuspend(::zx::unowned_channel(this->channel_));
-}
-
-Controller::ResultOf::DebugSuspend Controller::Call::DebugSuspend(::zx::unowned_channel _client_end) {
-  return ResultOf::DebugSuspend(std::move(_client_end));
-}
-
-template <>
-Controller::UnownedResultOf::DebugSuspend_Impl<Controller::DebugSuspendResponse>::DebugSuspend_Impl(::zx::unowned_channel _client_end, ::fidl::BytePart _response_buffer) {
-  FIDL_ALIGNDECL uint8_t _write_bytes[sizeof(DebugSuspendRequest)] = {};
-  ::fidl::BytePart _request_buffer(_write_bytes, sizeof(_write_bytes));
-  memset(_request_buffer.data(), 0, DebugSuspendRequest::PrimarySize);
-  _request_buffer.set_actual(sizeof(DebugSuspendRequest));
-  ::fidl::DecodedMessage<DebugSuspendRequest> _decoded_request(std::move(_request_buffer));
-  Super::SetResult(
-      Controller::InPlace::DebugSuspend(std::move(_client_end), std::move(_response_buffer)));
-}
-
-Controller::UnownedResultOf::DebugSuspend Controller::SyncClient::DebugSuspend(::fidl::BytePart _response_buffer) {
-  return UnownedResultOf::DebugSuspend(::zx::unowned_channel(this->channel_), std::move(_response_buffer));
-}
-
-Controller::UnownedResultOf::DebugSuspend Controller::Call::DebugSuspend(::zx::unowned_channel _client_end, ::fidl::BytePart _response_buffer) {
-  return UnownedResultOf::DebugSuspend(std::move(_client_end), std::move(_response_buffer));
-}
-
-::fidl::DecodeResult<Controller::DebugSuspendResponse> Controller::InPlace::DebugSuspend(::zx::unowned_channel _client_end, ::fidl::BytePart response_buffer) {
-  constexpr uint32_t _write_num_bytes = sizeof(DebugSuspendRequest);
-  ::fidl::internal::AlignedBuffer<_write_num_bytes> _write_bytes;
-  ::fidl::BytePart _request_buffer = _write_bytes.view();
-  _request_buffer.set_actual(_write_num_bytes);
-  ::fidl::DecodedMessage<DebugSuspendRequest> params(std::move(_request_buffer));
-  Controller::SetTransactionHeaderFor::DebugSuspendRequest(params);
-  auto _encode_request_result = ::fidl::Encode(std::move(params));
-  if (_encode_request_result.status != ZX_OK) {
-    return ::fidl::DecodeResult<Controller::DebugSuspendResponse>::FromFailure(
-        std::move(_encode_request_result));
-  }
-  auto _call_result = ::fidl::Call<DebugSuspendRequest, DebugSuspendResponse>(
-    std::move(_client_end), std::move(_encode_request_result.message), std::move(response_buffer));
-  if (_call_result.status != ZX_OK) {
-    return ::fidl::DecodeResult<Controller::DebugSuspendResponse>::FromFailure(
-        std::move(_call_result));
-  }
-  return ::fidl::Decode(std::move(_call_result.message));
-}
-
-template <>
 Controller::ResultOf::DebugResume_Impl<Controller::DebugResumeResponse>::DebugResume_Impl(::zx::unowned_channel _client_end) {
   constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<DebugResumeRequest, ::fidl::MessageDirection::kSending>();
   ::fidl::internal::AlignedBuffer<_kWriteAllocSize> _write_bytes_inlined;
@@ -1738,18 +1671,6 @@
           Interface::SetDriverLogFlagsCompleter::Sync(txn));
       return true;
     }
-    case kController_DebugSuspend_Ordinal:
-    case kController_DebugSuspend_GenOrdinal:
-    {
-      auto result = ::fidl::DecodeAs<DebugSuspendRequest>(msg);
-      if (result.status != ZX_OK) {
-        txn->Close(ZX_ERR_INVALID_ARGS);
-        return true;
-      }
-      impl->DebugSuspend(
-          Interface::DebugSuspendCompleter::Sync(txn));
-      return true;
-    }
     case kController_DebugResume_Ordinal:
     case kController_DebugResume_GenOrdinal:
     {
@@ -2331,42 +2252,6 @@
 }
 
 
-void Controller::Interface::DebugSuspendCompleterBase::Reply(int32_t status) {
-  constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<DebugSuspendResponse, ::fidl::MessageDirection::kSending>();
-  FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
-  auto& _response = *reinterpret_cast<DebugSuspendResponse*>(_write_bytes);
-  Controller::SetTransactionHeaderFor::DebugSuspendResponse(
-      ::fidl::DecodedMessage<DebugSuspendResponse>(
-          ::fidl::BytePart(reinterpret_cast<uint8_t*>(&_response),
-              DebugSuspendResponse::PrimarySize,
-              DebugSuspendResponse::PrimarySize)));
-  _response.status = std::move(status);
-  ::fidl::BytePart _response_bytes(_write_bytes, _kWriteAllocSize, sizeof(DebugSuspendResponse));
-  CompleterBase::SendReply(::fidl::DecodedMessage<DebugSuspendResponse>(std::move(_response_bytes)));
-}
-
-void Controller::Interface::DebugSuspendCompleterBase::Reply(::fidl::BytePart _buffer, int32_t status) {
-  if (_buffer.capacity() < DebugSuspendResponse::PrimarySize) {
-    CompleterBase::Close(ZX_ERR_INTERNAL);
-    return;
-  }
-  auto& _response = *reinterpret_cast<DebugSuspendResponse*>(_buffer.data());
-  Controller::SetTransactionHeaderFor::DebugSuspendResponse(
-      ::fidl::DecodedMessage<DebugSuspendResponse>(
-          ::fidl::BytePart(reinterpret_cast<uint8_t*>(&_response),
-              DebugSuspendResponse::PrimarySize,
-              DebugSuspendResponse::PrimarySize)));
-  _response.status = std::move(status);
-  _buffer.set_actual(sizeof(DebugSuspendResponse));
-  CompleterBase::SendReply(::fidl::DecodedMessage<DebugSuspendResponse>(std::move(_buffer)));
-}
-
-void Controller::Interface::DebugSuspendCompleterBase::Reply(::fidl::DecodedMessage<DebugSuspendResponse> params) {
-  Controller::SetTransactionHeaderFor::DebugSuspendResponse(params);
-  CompleterBase::SendReply(std::move(params));
-}
-
-
 void Controller::Interface::DebugResumeCompleterBase::Reply(int32_t status) {
   constexpr uint32_t _kWriteAllocSize = ::fidl::internal::ClampedMessageSize<DebugResumeResponse, ::fidl::MessageDirection::kSending>();
   FIDL_ALIGNDECL uint8_t _write_bytes[_kWriteAllocSize] = {};
@@ -2909,15 +2794,6 @@
   _msg.message()->_hdr.flags[0] |= FIDL_TXN_HEADER_UNION_FROM_XUNION_FLAG;
 }
 
-void Controller::SetTransactionHeaderFor::DebugSuspendRequest(const ::fidl::DecodedMessage<Controller::DebugSuspendRequest>& _msg) {
-  fidl_init_txn_header(&_msg.message()->_hdr, 0, kController_DebugSuspend_GenOrdinal);
-  _msg.message()->_hdr.flags[0] |= FIDL_TXN_HEADER_UNION_FROM_XUNION_FLAG;
-}
-void Controller::SetTransactionHeaderFor::DebugSuspendResponse(const ::fidl::DecodedMessage<Controller::DebugSuspendResponse>& _msg) {
-  fidl_init_txn_header(&_msg.message()->_hdr, 0, kController_DebugSuspend_GenOrdinal);
-  _msg.message()->_hdr.flags[0] |= FIDL_TXN_HEADER_UNION_FROM_XUNION_FLAG;
-}
-
 void Controller::SetTransactionHeaderFor::DebugResumeRequest(const ::fidl::DecodedMessage<Controller::DebugResumeRequest>& _msg) {
   fidl_init_txn_header(&_msg.message()->_hdr, 0, kController_DebugResume_GenOrdinal);
   _msg.message()->_hdr.flags[0] |= FIDL_TXN_HEADER_UNION_FROM_XUNION_FLAG;
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 bb3b8c7..970b68e 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
@@ -1248,8 +1248,6 @@
 extern "C" const fidl_type_t v1_fuchsia_device_ControllerGetDriverLogFlagsResponseTable;
 extern "C" const fidl_type_t v1_fuchsia_device_ControllerSetDriverLogFlagsRequestTable;
 extern "C" const fidl_type_t v1_fuchsia_device_ControllerSetDriverLogFlagsResponseTable;
-extern "C" const fidl_type_t v1_fuchsia_device_ControllerDebugSuspendRequestTable;
-extern "C" const fidl_type_t v1_fuchsia_device_ControllerDebugSuspendResponseTable;
 extern "C" const fidl_type_t v1_fuchsia_device_ControllerDebugResumeRequestTable;
 extern "C" const fidl_type_t v1_fuchsia_device_ControllerDebugResumeResponseTable;
 extern "C" const fidl_type_t v1_fuchsia_device_ControllerRunCompatibilityTestsRequestTable;
@@ -1484,23 +1482,6 @@
     using ResponseType = SetDriverLogFlagsResponse;
   };
 
-  struct DebugSuspendResponse final {
-    FIDL_ALIGNDECL
-    fidl_message_header_t _hdr;
-    int32_t status;
-
-    static constexpr const fidl_type_t* Type = &v1_fuchsia_device_ControllerDebugSuspendResponseTable;
-    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 bool HasPointer = false;
-    static constexpr bool ContainsUnion = false;
-    static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
-        ::fidl::internal::TransactionalMessageKind::kResponse;
-  };
-  using DebugSuspendRequest = ::fidl::AnyZeroArgMessage;
-
   struct DebugResumeResponse final {
     FIDL_ALIGNDECL
     fidl_message_header_t _hdr;
@@ -1927,22 +1908,6 @@
       using Super::operator*;
     };
     template <typename ResponseType>
-    class DebugSuspend_Impl final : private ::fidl::internal::OwnedSyncCallBase<ResponseType> {
-      using Super = ::fidl::internal::OwnedSyncCallBase<ResponseType>;
-     public:
-      DebugSuspend_Impl(::zx::unowned_channel _client_end);
-      ~DebugSuspend_Impl() = default;
-      DebugSuspend_Impl(DebugSuspend_Impl&& other) = default;
-      DebugSuspend_Impl& operator=(DebugSuspend_Impl&& other) = default;
-      using Super::status;
-      using Super::error;
-      using Super::ok;
-      using Super::Unwrap;
-      using Super::value;
-      using Super::operator->;
-      using Super::operator*;
-    };
-    template <typename ResponseType>
     class DebugResume_Impl final : private ::fidl::internal::OwnedSyncCallBase<ResponseType> {
       using Super = ::fidl::internal::OwnedSyncCallBase<ResponseType>;
      public:
@@ -2113,7 +2078,6 @@
     using GetEventHandle = GetEventHandle_Impl<GetEventHandleResponse>;
     using GetDriverLogFlags = GetDriverLogFlags_Impl<GetDriverLogFlagsResponse>;
     using SetDriverLogFlags = SetDriverLogFlags_Impl<SetDriverLogFlagsResponse>;
-    using DebugSuspend = DebugSuspend_Impl<DebugSuspendResponse>;
     using DebugResume = DebugResume_Impl<DebugResumeResponse>;
     using RunCompatibilityTests = RunCompatibilityTests_Impl<RunCompatibilityTestsResponse>;
     using GetDevicePowerCaps = GetDevicePowerCaps_Impl<GetDevicePowerCapsResponse>;
@@ -2276,22 +2240,6 @@
       using Super::operator*;
     };
     template <typename ResponseType>
-    class DebugSuspend_Impl final : private ::fidl::internal::UnownedSyncCallBase<ResponseType> {
-      using Super = ::fidl::internal::UnownedSyncCallBase<ResponseType>;
-     public:
-      DebugSuspend_Impl(::zx::unowned_channel _client_end, ::fidl::BytePart _response_buffer);
-      ~DebugSuspend_Impl() = default;
-      DebugSuspend_Impl(DebugSuspend_Impl&& other) = default;
-      DebugSuspend_Impl& operator=(DebugSuspend_Impl&& other) = default;
-      using Super::status;
-      using Super::error;
-      using Super::ok;
-      using Super::Unwrap;
-      using Super::value;
-      using Super::operator->;
-      using Super::operator*;
-    };
-    template <typename ResponseType>
     class DebugResume_Impl final : private ::fidl::internal::UnownedSyncCallBase<ResponseType> {
       using Super = ::fidl::internal::UnownedSyncCallBase<ResponseType>;
      public:
@@ -2462,7 +2410,6 @@
     using GetEventHandle = GetEventHandle_Impl<GetEventHandleResponse>;
     using GetDriverLogFlags = GetDriverLogFlags_Impl<GetDriverLogFlagsResponse>;
     using SetDriverLogFlags = SetDriverLogFlags_Impl<SetDriverLogFlagsResponse>;
-    using DebugSuspend = DebugSuspend_Impl<DebugSuspendResponse>;
     using DebugResume = DebugResume_Impl<DebugResumeResponse>;
     using RunCompatibilityTests = RunCompatibilityTests_Impl<RunCompatibilityTestsResponse>;
     using GetDevicePowerCaps = GetDevicePowerCaps_Impl<GetDevicePowerCapsResponse>;
@@ -2568,14 +2515,6 @@
     // Caller provides the backing storage for FIDL message via request and response buffers.
     UnownedResultOf::SetDriverLogFlags SetDriverLogFlags(::fidl::BytePart _request_buffer, uint32_t clear_flags, uint32_t set_flags, ::fidl::BytePart _response_buffer);
 
-    // Debug command: execute the device's suspend hook
-    // Allocates 40 bytes of message buffer on the stack. No heap allocation necessary.
-    ResultOf::DebugSuspend DebugSuspend();
-
-    // Debug command: execute the device's suspend hook
-    // Caller provides the backing storage for FIDL message via request and response buffers.
-    UnownedResultOf::DebugSuspend DebugSuspend(::fidl::BytePart _response_buffer);
-
     // Debug command: execute the device's resume hook
     // Allocates 40 bytes of message buffer on the stack. No heap allocation necessary.
     ResultOf::DebugResume DebugResume();
@@ -2777,14 +2716,6 @@
     // Caller provides the backing storage for FIDL message via request and response buffers.
     static UnownedResultOf::SetDriverLogFlags SetDriverLogFlags(::zx::unowned_channel _client_end, ::fidl::BytePart _request_buffer, uint32_t clear_flags, uint32_t set_flags, ::fidl::BytePart _response_buffer);
 
-    // Debug command: execute the device's suspend hook
-    // Allocates 40 bytes of message buffer on the stack. No heap allocation necessary.
-    static ResultOf::DebugSuspend DebugSuspend(::zx::unowned_channel _client_end);
-
-    // Debug command: execute the device's suspend hook
-    // Caller provides the backing storage for FIDL message via request and response buffers.
-    static UnownedResultOf::DebugSuspend DebugSuspend(::zx::unowned_channel _client_end, ::fidl::BytePart _response_buffer);
-
     // Debug command: execute the device's resume hook
     // Allocates 40 bytes of message buffer on the stack. No heap allocation necessary.
     static ResultOf::DebugResume DebugResume(::zx::unowned_channel _client_end);
@@ -2935,9 +2866,6 @@
     // Each set bit in `set_flags` will then be set in the log flags state.
     static ::fidl::DecodeResult<SetDriverLogFlagsResponse> SetDriverLogFlags(::zx::unowned_channel _client_end, ::fidl::DecodedMessage<SetDriverLogFlagsRequest> params, ::fidl::BytePart response_buffer);
 
-    // Debug command: execute the device's suspend hook
-    static ::fidl::DecodeResult<DebugSuspendResponse> DebugSuspend(::zx::unowned_channel _client_end, ::fidl::BytePart response_buffer);
-
     // Debug command: execute the device's resume hook
     static ::fidl::DecodeResult<DebugResumeResponse> DebugResume(::zx::unowned_channel _client_end, ::fidl::BytePart response_buffer);
 
@@ -3131,20 +3059,6 @@
 
     virtual void SetDriverLogFlags(uint32_t clear_flags, uint32_t set_flags, SetDriverLogFlagsCompleter::Sync _completer) = 0;
 
-    class DebugSuspendCompleterBase : public _Base {
-     public:
-      void Reply(int32_t status);
-      void Reply(::fidl::BytePart _buffer, int32_t status);
-      void Reply(::fidl::DecodedMessage<DebugSuspendResponse> params);
-
-     protected:
-      using ::fidl::CompleterBase::CompleterBase;
-    };
-
-    using DebugSuspendCompleter = ::fidl::Completer<DebugSuspendCompleterBase>;
-
-    virtual void DebugSuspend(DebugSuspendCompleter::Sync _completer) = 0;
-
     class DebugResumeCompleterBase : public _Base {
      public:
       void Reply(int32_t status);
@@ -3340,8 +3254,6 @@
     static void GetDriverLogFlagsResponse(const ::fidl::DecodedMessage<Controller::GetDriverLogFlagsResponse>& _msg);
     static void SetDriverLogFlagsRequest(const ::fidl::DecodedMessage<Controller::SetDriverLogFlagsRequest>& _msg);
     static void SetDriverLogFlagsResponse(const ::fidl::DecodedMessage<Controller::SetDriverLogFlagsResponse>& _msg);
-    static void DebugSuspendRequest(const ::fidl::DecodedMessage<Controller::DebugSuspendRequest>& _msg);
-    static void DebugSuspendResponse(const ::fidl::DecodedMessage<Controller::DebugSuspendResponse>& _msg);
     static void DebugResumeRequest(const ::fidl::DecodedMessage<Controller::DebugResumeRequest>& _msg);
     static void DebugResumeResponse(const ::fidl::DecodedMessage<Controller::DebugResumeResponse>& _msg);
     static void RunCompatibilityTestsRequest(const ::fidl::DecodedMessage<Controller::RunCompatibilityTestsRequest>& _msg);
@@ -3596,14 +3508,6 @@
 static_assert(offsetof(::llcpp::fuchsia::device::Controller::SetDriverLogFlagsResponse, status) == 16);
 
 template <>
-struct IsFidlType<::llcpp::fuchsia::device::Controller::DebugSuspendResponse> : public std::true_type {};
-template <>
-struct IsFidlMessage<::llcpp::fuchsia::device::Controller::DebugSuspendResponse> : public std::true_type {};
-static_assert(sizeof(::llcpp::fuchsia::device::Controller::DebugSuspendResponse)
-    == ::llcpp::fuchsia::device::Controller::DebugSuspendResponse::PrimarySize);
-static_assert(offsetof(::llcpp::fuchsia::device::Controller::DebugSuspendResponse, status) == 16);
-
-template <>
 struct IsFidlType<::llcpp::fuchsia::device::Controller::DebugResumeResponse> : public std::true_type {};
 template <>
 struct IsFidlMessage<::llcpp::fuchsia::device::Controller::DebugResumeResponse> : public std::true_type {};
diff --git a/zircon/system/ulib/ddk/include/ddk/device.h b/zircon/system/ulib/ddk/include/ddk/device.h
index 54d5929..4c85553 100644
--- a/zircon/system/ulib/ddk/include/ddk/device.h
+++ b/zircon/system/ulib/ddk/include/ddk/device.h
@@ -324,9 +324,6 @@
   //
 
   zx_status_t (*configure_auto_suspend)(void* ctx, bool enable, uint8_t deepest_sleep_state);
-  // Stops the device and puts it in a low power mode
-  // DEPRECATED: Use suspend_new instead.
-  zx_status_t (*suspend)(void* ctx, uint32_t flags);
 
   // This hook is never invoked.
   // DEPRECATED: Use resume_new instead.
diff --git a/zircon/system/ulib/ddktl/include/ddktl/device-internal.h b/zircon/system/ulib/ddktl/include/ddktl/device-internal.h
index 506555c..8b939b7 100644
--- a/zircon/system/ulib/ddktl/include/ddktl/device-internal.h
+++ b/zircon/system/ulib/ddktl/include/ddktl/device-internal.h
@@ -248,8 +248,8 @@
 template <typename D>
 constexpr void CheckGetSizable() {
   static_assert(has_ddk_get_size<D>::value, "GetSizable classes must implement DdkGetSize");
-  static_assert(std::is_same<decltype(&D::DdkGetSize), zx_off_t (D::*)(void)>::value
-                || std::is_same<decltype(&D::DdkGetSize), zx_off_t (D::*)(void) const>::value,
+  static_assert(std::is_same<decltype(&D::DdkGetSize), zx_off_t (D::*)(void)>::value ||
+                    std::is_same<decltype(&D::DdkGetSize), zx_off_t (D::*)(void) const>::value,
                 "DdkGetSize must be a public non-static member function with signature "
                 "'zx_off_t DdkGetSize()'.");
 }
@@ -265,16 +265,6 @@
       "'zx_status_t DdkMessage(fidl_msg_t*, fidl_txn_t*)'.");
 }
 
-DECLARE_HAS_MEMBER_FN(has_ddk_suspend, DdkSuspend);
-
-template <typename D>
-constexpr void CheckSuspendable() {
-  static_assert(has_ddk_suspend<D>::value, "Suspendable classes must implement DdkSuspend");
-  static_assert(std::is_same<decltype(&D::DdkSuspend), zx_status_t (D::*)(uint32_t)>::value,
-                "DdkSuspend must be a public non-static member function with signature "
-                "'zx_status_t DdkSuspend(uint32_t)'.");
-}
-
 DECLARE_HAS_MEMBER_FN(has_ddk_suspend_new, DdkSuspendNew);
 
 template <typename D>
diff --git a/zircon/system/ulib/ddktl/include/ddktl/device.h b/zircon/system/ulib/ddktl/include/ddktl/device.h
index 56c3611..1c1050af2 100644
--- a/zircon/system/ulib/ddktl/include/ddktl/device.h
+++ b/zircon/system/ulib/ddktl/include/ddktl/device.h
@@ -80,8 +80,6 @@
 // |                          |                                                    |
 // | ddk::GetSizable          | zx_off_t DdkGetSize()                              |
 // |                          |                                                    |
-// | ddk::Suspendable         | zx_status_t DdkSuspend(uint32_t flags)             |
-// |                          |                                                    |
 // | ddk::Resumable           | zx_status_t DdkResume(uint32_t flags)              |
 // |                          |                                                    |
 // | ddk::UnbindableDeprecated| void DdkUnbindDeprecated()                         |
@@ -289,20 +287,6 @@
 };
 
 template <typename D>
-class Suspendable : public base_mixin {
- protected:
-  static constexpr void InitOp(zx_protocol_device_t* proto) {
-    internal::CheckSuspendable<D>();
-    proto->suspend = Suspend;
-  }
-
- private:
-  static zx_status_t Suspend(void* ctx, uint32_t flags) {
-    return static_cast<D*>(ctx)->DdkSuspend(flags);
-  }
-};
-
-template <typename D>
 class SuspendableNew : public base_mixin {
  protected:
   static constexpr void InitOp(zx_protocol_device_t* proto) {
@@ -558,7 +542,7 @@
 // zx_protocol_device_t methods.
 template <class D>
 using FullDevice = Device<D, GetProtocolable, Initializable, Openable, Closable, UnbindableNew,
-                          Readable, Writable, GetSizable, Suspendable, Resumable, Rxrpcable>;
+                          Readable, Writable, GetSizable, SuspendableNew, Resumable, Rxrpcable>;
 
 }  // namespace ddk
 
diff --git a/zircon/system/ulib/ddktl/test/device-tests.cc b/zircon/system/ulib/ddktl/test/device-tests.cc
index 032ded3..842d4dd 100644
--- a/zircon/system/ulib/ddktl/test/device-tests.cc
+++ b/zircon/system/ulib/ddktl/test/device-tests.cc
@@ -69,8 +69,10 @@
 zx_status_t DdkMessage(fidl_msg_t* msg, fidl_txn_t* txn) { return ZX_OK; }
 END_SUCCESS_CASE
 
-BEGIN_SUCCESS_CASE(Suspendable)
-zx_status_t DdkSuspend(uint32_t flags) { return ZX_OK; }
+BEGIN_SUCCESS_CASE(SuspendableNew)
+// As the txn does not contain a valid device pointer, the destructor won't throw an error
+// if we don't reply.
+void DdkSuspendNew(ddk::SuspendTxn txn) {}
 END_SUCCESS_CASE
 
 BEGIN_SUCCESS_CASE(Resumable)
@@ -134,10 +136,7 @@
     return 0;
   }
 
-  zx_status_t DdkSuspend(uint32_t flags) {
-    suspend_called = true;
-    return ZX_OK;
-  }
+  void DdkSuspendNew(ddk::SuspendTxn txn) { suspend_called = true; }
 
   zx_status_t DdkResume(uint32_t flags) {
     resume_called = true;
@@ -183,7 +182,7 @@
   EXPECT_EQ(ZX_OK, ops->read(ctx, nullptr, 0, 0, nullptr), "");
   EXPECT_EQ(ZX_OK, ops->write(ctx, nullptr, 0, 0, nullptr), "");
   EXPECT_EQ(0, ops->get_size(ctx), "");
-  EXPECT_EQ(ZX_OK, ops->suspend(ctx, 0), "");
+  ops->suspend_new(ctx, 2, false, 0);
   EXPECT_EQ(ZX_OK, ops->resume(ctx, 0), "");
   EXPECT_EQ(ZX_OK, ops->rxrpc(ctx, 0), "");
 
@@ -226,7 +225,7 @@
 DEFINE_FAIL_CASE(Writable)
 DEFINE_FAIL_CASE(IotxnQueueable)
 DEFINE_FAIL_CASE(GetSizable)
-DEFINE_FAIL_CASE(Suspendable)
+DEFINE_FAIL_CASE(SuspendableNew)
 DEFINE_FAIL_CASE(Resumable)
 DEFINE_FAIL_CASE(Rxrpcable)
 
@@ -289,7 +288,7 @@
 RUN_NAMED_TEST("ddk::Readable", do_test<TestReadable>);
 RUN_NAMED_TEST("ddk::Writable", do_test<TestWritable>);
 RUN_NAMED_TEST("ddk::GetSizable", do_test<TestGetSizable>);
-RUN_NAMED_TEST("ddk::Suspendable", do_test<TestSuspendable>);
+RUN_NAMED_TEST("ddk::SuspendableNew", do_test<TestSuspendableNew>);
 RUN_NAMED_TEST("ddk::Resumable", do_test<TestResumable>);
 RUN_NAMED_TEST("ddk::Rxrpcable", do_test<TestRxrpcable>);