#define ZFCP_STATUS_ADAPTER_QDIOUP             0x00000002
 #define ZFCP_STATUS_ADAPTER_XCONFIG_OK         0x00000008
 #define ZFCP_STATUS_ADAPTER_HOST_CON_INIT      0x00000010
-#define ZFCP_STATUS_ADAPTER_ERP_THREAD_UP      0x00000020
-#define ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL    0x00000080
 #define ZFCP_STATUS_ADAPTER_ERP_PENDING                0x00000100
 #define ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED     0x00000200
 
        atomic_t                status;            /* status of this adapter */
        struct list_head        erp_ready_head;    /* error recovery for this
                                                      adapter/devices */
+       wait_queue_head_t       erp_ready_wq;
        struct list_head        erp_running_head;
        rwlock_t                erp_lock;
-       struct semaphore        erp_ready_sem;
-       wait_queue_head_t       erp_thread_wqh;
        wait_queue_head_t       erp_done_wqh;
        struct zfcp_erp_action  erp_action;        /* pending error recovery */
         atomic_t                erp_counter;
                                                      actions */
        u32                     erp_low_mem_count; /* nr of erp actions waiting
                                                      for memory */
+       struct task_struct      *erp_thread;
        struct zfcp_wka_ports   *gs;               /* generic services */
        struct zfcp_dbf         *dbf;              /* debug traces */
        struct zfcp_adapter_mempool     pool;      /* Adapter memory pools */
 
 #define KMSG_COMPONENT "zfcp"
 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
 
+#include <linux/kthread.h>
 #include "zfcp_ext.h"
 
 #define ZFCP_MAX_ERPS                   3
 
        list_move(&act->list, &act->adapter->erp_ready_head);
        zfcp_dbf_rec_action("erardy1", act);
-       up(&adapter->erp_ready_sem);
+       wake_up(&adapter->erp_ready_wq);
        zfcp_dbf_rec_thread("erardy2", adapter->dbf);
 }
 
        int retval = 1, need;
        struct zfcp_erp_action *act = NULL;
 
-       if (!(atomic_read(&adapter->status) &
-             ZFCP_STATUS_ADAPTER_ERP_THREAD_UP))
+       if (!adapter->erp_thread)
                return -EIO;
 
        need = zfcp_erp_required_act(want, adapter, port, unit);
                goto out;
        ++adapter->erp_total_count;
        list_add_tail(&act->list, &adapter->erp_ready_head);
-       up(&adapter->erp_ready_sem);
+       wake_up(&adapter->erp_ready_wq);
        zfcp_dbf_rec_thread("eracte1", adapter->dbf);
        retval = 0;
  out:
                }
 
                zfcp_dbf_rec_thread_lock("erasfx1", adapter->dbf);
-               down(&adapter->erp_ready_sem);
+               wait_event(adapter->erp_ready_wq,
+                          !list_empty(&adapter->erp_ready_head));
                zfcp_dbf_rec_thread_lock("erasfx2", adapter->dbf);
                if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT)
                        break;
                return ZFCP_ERP_FAILED;
 
        zfcp_dbf_rec_thread_lock("erasox1", adapter->dbf);
-       down(&adapter->erp_ready_sem);
+       wait_event(adapter->erp_ready_wq,
+                  !list_empty(&adapter->erp_ready_head));
        zfcp_dbf_rec_thread_lock("erasox2", adapter->dbf);
        if (act->status & ZFCP_STATUS_ERP_TIMEDOUT)
                return ZFCP_ERP_FAILED;
        struct list_head *next;
        struct zfcp_erp_action *act;
        unsigned long flags;
-       int ignore;
-
-       daemonize("zfcperp%s", dev_name(&adapter->ccw_device->dev));
-       /* Block all signals */
-       siginitsetinv(¤t->blocked, 0);
-       atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status);
-       wake_up(&adapter->erp_thread_wqh);
-
-       while (!(atomic_read(&adapter->status) &
-                ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL)) {
 
+       for (;;) {
                zfcp_dbf_rec_thread_lock("erthrd1", adapter->dbf);
-               ignore = down_interruptible(&adapter->erp_ready_sem);
+               wait_event_interruptible(adapter->erp_ready_wq,
+                          !list_empty(&adapter->erp_ready_head) ||
+                          kthread_should_stop());
                zfcp_dbf_rec_thread_lock("erthrd2", adapter->dbf);
 
+               if (kthread_should_stop())
+                       break;
+
                write_lock_irqsave(&adapter->erp_lock, flags);
                next = adapter->erp_ready_head.next;
                write_unlock_irqrestore(&adapter->erp_lock, flags);
                }
        }
 
-       atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status);
-       wake_up(&adapter->erp_thread_wqh);
-
        return 0;
 }
 
  */
 int zfcp_erp_thread_setup(struct zfcp_adapter *adapter)
 {
-       int retval;
+       struct task_struct *thread;
 
-       atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status);
-       retval = kernel_thread(zfcp_erp_thread, adapter, SIGCHLD);
-       if (retval < 0) {
+       thread = kthread_run(zfcp_erp_thread, adapter, "zfcperp%s",
+                            dev_name(&adapter->ccw_device->dev));
+       if (IS_ERR(thread)) {
                dev_err(&adapter->ccw_device->dev,
                        "Creating an ERP thread for the FCP device failed.\n");
-               return retval;
+               return PTR_ERR(thread);
        }
-       wait_event(adapter->erp_thread_wqh,
-                  atomic_read(&adapter->status) &
-                       ZFCP_STATUS_ADAPTER_ERP_THREAD_UP);
+
+       adapter->erp_thread = thread;
        return 0;
 }
 
  */
 void zfcp_erp_thread_kill(struct zfcp_adapter *adapter)
 {
-       atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL, &adapter->status);
-       up(&adapter->erp_ready_sem);
-       zfcp_dbf_rec_thread_lock("erthrk1", adapter->dbf);
-
-       wait_event(adapter->erp_thread_wqh,
-                  !(atomic_read(&adapter->status) &
-                               ZFCP_STATUS_ADAPTER_ERP_THREAD_UP));
-
-       atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL,
-                         &adapter->status);
+       kthread_stop(adapter->erp_thread);
+       adapter->erp_thread = NULL;
 }
 
 /**