diff --git a/zircon/system/core/devmgr/devcoordinator/device.cpp b/zircon/system/core/devmgr/devcoordinator/device.cpp
index ffd62ee5335d39766567cb8e9f9f3c790bec5cae..ac03e06194cd14e27f021e980855f087a9cb1924 100644
--- a/zircon/system/core/devmgr/devcoordinator/device.cpp
+++ b/zircon/system/core/devmgr/devcoordinator/device.cpp
@@ -11,6 +11,7 @@
 #include "coordinator.h"
 #include "devfs.h"
 #include "fidl.h"
+#include "suspend-task.h"
 
 namespace devmgr {
 
@@ -193,6 +194,17 @@ zx_status_t Device::SignalReadyForBind(zx::duration delay) {
     return publish_task_.PostDelayed(this->coordinator->dispatcher(), delay);
 }
 
+fbl::RefPtr<SuspendTask> Device::RequestSuspendTask(uint32_t suspend_flags) {
+    if (active_suspend_) {
+        // We don't support different types of suspends concurrently, and
+        // shouldn't be able to reach this state.
+        ZX_ASSERT(suspend_flags == active_suspend_->suspend_flags());
+    } else {
+        active_suspend_ = SuspendTask::Create(fbl::WrapRefPtr(this), suspend_flags);
+    }
+    return active_suspend_;
+}
+
 zx_status_t Device::SendSuspend(uint32_t flags, SuspendCompletion completion) {
     if (suspend_completion_) {
         // We already have a pending suspend
@@ -212,6 +224,7 @@ void Device::CompleteSuspend(zx_status_t status) {
         state_ = Device::State::kSuspended;
     }
 
+    active_suspend_ = nullptr;
     SuspendCompletion completion(std::move(suspend_completion_));
     if (completion) {
         completion(status);
diff --git a/zircon/system/core/devmgr/devcoordinator/device.h b/zircon/system/core/devmgr/devcoordinator/device.h
index 9caa7628bc82827036fd5d289fe6e63b024c04ec..6dcfaa60b4408b639af920700a415254ab5a6c8c 100644
--- a/zircon/system/core/devmgr/devcoordinator/device.h
+++ b/zircon/system/core/devmgr/devcoordinator/device.h
@@ -24,6 +24,7 @@ class Coordinator;
 class Devhost;
 struct Devnode;
 class SuspendContext;
+class SuspendTask;
 
 // clang-format off
 
@@ -252,6 +253,9 @@ struct Device : public fbl::RefCounted<Device>, public AsyncLoopRefCountedRpcHan
 
     State state() const { return state_; }
 
+    // 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);
 private:
     zx_status_t HandleRead();
 
@@ -289,8 +293,11 @@ private:
     // The current state of the device
     State state_ = State::kActive;
 
+    // If a suspend is in-progress, this task represents it.
+    fbl::RefPtr<SuspendTask> active_suspend_;
     // If a suspend is in-progress, this completion will be invoked when it is
-    // completed.
+    // completed.  It will likely mark |active_suspend_| as completed and clear
+    // it.
     SuspendCompletion suspend_completion_;
 };
 
diff --git a/zircon/system/core/devmgr/devcoordinator/suspend-task.cpp b/zircon/system/core/devmgr/devcoordinator/suspend-task.cpp
index 6035380c15cd33bb97e95c61794dbec58daec45c..2821d3d581344f0d9e74aaf5f2928bbf5a925919 100644
--- a/zircon/system/core/devmgr/devcoordinator/suspend-task.cpp
+++ b/zircon/system/core/devmgr/devcoordinator/suspend-task.cpp
@@ -28,8 +28,8 @@ void SuspendTask::Run() {
         case Device::State::kSuspended: continue;
         case Device::State::kActive: break;
         }
-        auto task = SuspendTask::Create(fbl::WrapRefPtr(&child), flags_);
-        AddDependency(std::move(task));
+
+        AddDependency(child.RequestSuspendTask(flags_));
         found_more_dependencies = true;
     }
     if (found_more_dependencies) {
@@ -42,8 +42,7 @@ void SuspendTask::Run() {
         switch (device_->proxy->state()) {
         case Device::State::kSuspended: break;
         case Device::State::kActive: {
-            auto task = SuspendTask::Create(device_->proxy, flags_);
-            AddDependency(std::move(task));
+            AddDependency(device_->proxy->RequestSuspendTask(flags_));
             return;
         }
         }
diff --git a/zircon/system/core/devmgr/devcoordinator/suspend-task.h b/zircon/system/core/devmgr/devcoordinator/suspend-task.h
index 96f2b676dbf03f0e9d1ca843e19e8381c28fecc2..4d781af29fd7261132ae0a9e1cb378185ac6e996 100644
--- a/zircon/system/core/devmgr/devcoordinator/suspend-task.h
+++ b/zircon/system/core/devmgr/devcoordinator/suspend-task.h
@@ -17,6 +17,8 @@ public:
     // Don/t invoke this, use Create
     SuspendTask(fbl::RefPtr<Device> device, uint32_t flags, Completion completion);
 
+    uint32_t suspend_flags() { return flags_; }
+
     ~SuspendTask() final;
 private:
     void Run() final;