fsm_state_notify(ctl->md, state);
 }
 
+static void fsm_release_command(struct kref *ref)
+{
+       struct t7xx_fsm_command *cmd = container_of(ref, typeof(*cmd), refcnt);
+
+       kfree(cmd);
+}
+
 static void fsm_finish_command(struct t7xx_fsm_ctl *ctl, struct t7xx_fsm_command *cmd, int result)
 {
        if (cmd->flag & FSM_CMD_FLAG_WAIT_FOR_COMPLETION) {
-               *cmd->ret = result;
-               complete_all(cmd->done);
+               cmd->result = result;
+               complete_all(&cmd->done);
        }
 
-       kfree(cmd);
+       kref_put(&cmd->refcnt, fsm_release_command);
 }
 
 static void fsm_del_kf_event(struct t7xx_fsm_event *event)
 
 int t7xx_fsm_append_cmd(struct t7xx_fsm_ctl *ctl, enum t7xx_fsm_cmd_state cmd_id, unsigned int flag)
 {
-       DECLARE_COMPLETION_ONSTACK(done);
        struct t7xx_fsm_command *cmd;
        unsigned long flags;
        int ret;
        INIT_LIST_HEAD(&cmd->entry);
        cmd->cmd_id = cmd_id;
        cmd->flag = flag;
+       kref_init(&cmd->refcnt);
        if (flag & FSM_CMD_FLAG_WAIT_FOR_COMPLETION) {
-               cmd->done = &done;
-               cmd->ret = &ret;
+               init_completion(&cmd->done);
+               kref_get(&cmd->refcnt);
        }
 
+       kref_get(&cmd->refcnt);
        spin_lock_irqsave(&ctl->command_lock, flags);
        list_add_tail(&cmd->entry, &ctl->command_queue);
        spin_unlock_irqrestore(&ctl->command_lock, flags);
        if (flag & FSM_CMD_FLAG_WAIT_FOR_COMPLETION) {
                unsigned long wait_ret;
 
-               wait_ret = wait_for_completion_timeout(&done,
+               wait_ret = wait_for_completion_timeout(&cmd->done,
                                                       msecs_to_jiffies(FSM_CMD_TIMEOUT_MS));
-               if (!wait_ret)
-                       return -ETIMEDOUT;
 
+               ret = wait_ret ? cmd->result : -ETIMEDOUT;
+               kref_put(&cmd->refcnt, fsm_release_command);
                return ret;
        }