* @cq: pointer to the specific Control queue
  *
  * This is the main initialization routine for the Control Send Queue
- * Prior to calling this function, drivers *MUST* set the following fields
+ * Prior to calling this function, the driver *MUST* set the following fields
  * in the cq->structure:
  *     - cq->num_sq_entries
  *     - cq->sq_buf_size
  * @cq: pointer to the specific Control queue
  *
  * The main initialization routine for the Admin Receive (Event) Queue.
- * Prior to calling this function, drivers *MUST* set the following fields
+ * Prior to calling this function, the driver *MUST* set the following fields
  * in the cq->structure:
  *     - cq->num_rq_entries
  *     - cq->rq_buf_size
        return 0;
 
 init_ctrlq_free_rq:
-       if (cq->rq.count) {
-               ice_shutdown_rq(hw, cq);
-               mutex_destroy(&cq->rq_lock);
-       }
-       if (cq->sq.count) {
-               ice_shutdown_sq(hw, cq);
-               mutex_destroy(&cq->sq_lock);
-       }
+       ice_shutdown_rq(hw, cq);
+       ice_shutdown_sq(hw, cq);
        return status;
 }
 
  * @hw: pointer to the hardware structure
  * @q_type: specific Control queue type
  *
- * Prior to calling this function, drivers *MUST* set the following fields
+ * Prior to calling this function, the driver *MUST* set the following fields
  * in the cq->structure:
  *     - cq->num_sq_entries
  *     - cq->num_rq_entries
  *     - cq->rq_buf_size
  *     - cq->sq_buf_size
+ *
+ * NOTE: this function does not initialize the controlq locks
  */
 static enum ice_status ice_init_ctrlq(struct ice_hw *hw, enum ice_ctl_q q_type)
 {
            !cq->rq_buf_size || !cq->sq_buf_size) {
                return ICE_ERR_CFG;
        }
-       mutex_init(&cq->sq_lock);
-       mutex_init(&cq->rq_lock);
 
        /* setup SQ command write back timeout */
        cq->sq_cmd_timeout = ICE_CTL_Q_SQ_CMD_TIMEOUT;
        /* allocate the ATQ */
        ret_code = ice_init_sq(hw, cq);
        if (ret_code)
-               goto init_ctrlq_destroy_locks;
+               return ret_code;
 
        /* allocate the ARQ */
        ret_code = ice_init_rq(hw, cq);
 
 init_ctrlq_free_sq:
        ice_shutdown_sq(hw, cq);
-init_ctrlq_destroy_locks:
-       mutex_destroy(&cq->sq_lock);
-       mutex_destroy(&cq->rq_lock);
        return ret_code;
 }
 
  * ice_init_all_ctrlq - main initialization routine for all control queues
  * @hw: pointer to the hardware structure
  *
- * Prior to calling this function, drivers *MUST* set the following fields
+ * Prior to calling this function, the driver MUST* set the following fields
  * in the cq->structure for all control queues:
  *     - cq->num_sq_entries
  *     - cq->num_rq_entries
  *     - cq->rq_buf_size
  *     - cq->sq_buf_size
+ *
+ * NOTE: this function does not initialize the controlq locks.
  */
 enum ice_status ice_init_all_ctrlq(struct ice_hw *hw)
 {
        return ice_init_ctrlq(hw, ICE_CTL_Q_MAILBOX);
 }
 
+/**
+ * ice_init_ctrlq_locks - Initialize locks for a control queue
+ * @cq: pointer to the control queue
+ *
+ * Initializes the send and receive queue locks for a given control queue.
+ */
+static void ice_init_ctrlq_locks(struct ice_ctl_q_info *cq)
+{
+       mutex_init(&cq->sq_lock);
+       mutex_init(&cq->rq_lock);
+}
+
+/**
+ * ice_create_all_ctrlq - main initialization routine for all control queues
+ * @hw: pointer to the hardware structure
+ *
+ * Prior to calling this function, the driver *MUST* set the following fields
+ * in the cq->structure for all control queues:
+ *     - cq->num_sq_entries
+ *     - cq->num_rq_entries
+ *     - cq->rq_buf_size
+ *     - cq->sq_buf_size
+ *
+ * This function creates all the control queue locks and then calls
+ * ice_init_all_ctrlq. It should be called once during driver load. If the
+ * driver needs to re-initialize control queues at run time it should call
+ * ice_init_all_ctrlq instead.
+ */
+enum ice_status ice_create_all_ctrlq(struct ice_hw *hw)
+{
+       ice_init_ctrlq_locks(&hw->adminq);
+       ice_init_ctrlq_locks(&hw->mailboxq);
+
+       return ice_init_all_ctrlq(hw);
+}
+
 /**
  * ice_shutdown_ctrlq - shutdown routine for any control queue
  * @hw: pointer to the hardware structure
  * @q_type: specific Control queue type
+ *
+ * NOTE: this function does not destroy the control queue locks.
  */
 static void ice_shutdown_ctrlq(struct ice_hw *hw, enum ice_ctl_q q_type)
 {
                return;
        }
 
-       if (cq->sq.count) {
-               ice_shutdown_sq(hw, cq);
-               mutex_destroy(&cq->sq_lock);
-       }
-       if (cq->rq.count) {
-               ice_shutdown_rq(hw, cq);
-               mutex_destroy(&cq->rq_lock);
-       }
+       ice_shutdown_sq(hw, cq);
+       ice_shutdown_rq(hw, cq);
 }
 
 /**
  * ice_shutdown_all_ctrlq - shutdown routine for all control queues
  * @hw: pointer to the hardware structure
+ *
+ * NOTE: this function does not destroy the control queue locks. The driver
+ * may call this at runtime to shutdown and later restart control queues, such
+ * as in response to a reset event.
  */
 void ice_shutdown_all_ctrlq(struct ice_hw *hw)
 {
        ice_shutdown_ctrlq(hw, ICE_CTL_Q_MAILBOX);
 }
 
+/**
+ * ice_destroy_ctrlq_locks - Destroy locks for a control queue
+ * @cq: pointer to the control queue
+ *
+ * Destroys the send and receive queue locks for a given control queue.
+ */
+static void
+ice_destroy_ctrlq_locks(struct ice_ctl_q_info *cq)
+{
+       mutex_destroy(&cq->sq_lock);
+       mutex_destroy(&cq->rq_lock);
+}
+
+/**
+ * ice_destroy_all_ctrlq - exit routine for all control queues
+ * @hw: pointer to the hardware structure
+ *
+ * This function shuts down all the control queues and then destroys the
+ * control queue locks. It should be called once during driver unload. The
+ * driver should call ice_shutdown_all_ctrlq if it needs to shut down and
+ * reinitialize control queues, such as in response to a reset event.
+ */
+void ice_destroy_all_ctrlq(struct ice_hw *hw)
+{
+       /* shut down all the control queues first */
+       ice_shutdown_all_ctrlq(hw);
+
+       ice_destroy_ctrlq_locks(&hw->adminq);
+       ice_destroy_ctrlq_locks(&hw->mailboxq);
+}
+
 /**
  * ice_clean_sq - cleans Admin send queue (ATQ)
  * @hw: pointer to the hardware structure