static void ap_interrupt_handler(void *unused1, void *unused2);
 static void ap_reset(struct ap_device *ap_dev);
 static void ap_config_timeout(unsigned long ptr);
+static int ap_select_domain(void);
 
 /*
  * Module description.
 
 /* Suspend flag */
 static int ap_suspend_flag;
+/* Flag to check if domain was set through module parameter domain=. This is
+ * important when supsend and resume is done in a z/VM environment where the
+ * domain might change. */
+static int user_set_domain = 0;
 static struct bus_type ap_bus_type;
 
 /**
                        destroy_workqueue(ap_work_queue);
                        ap_work_queue = NULL;
                }
+
                tasklet_disable(&ap_tasklet);
        }
        /* Poll on the device until all requests are finished. */
                spin_unlock_bh(&ap_dev->lock);
        } while ((flags & 1) || (flags & 2));
 
-       ap_device_remove(dev);
+       spin_lock_bh(&ap_dev->lock);
+       ap_dev->unregistered = 1;
+       spin_unlock_bh(&ap_dev->lock);
+
        return 0;
 }
 
                ap_suspend_flag = 0;
                if (!ap_interrupts_available())
                        ap_interrupt_indicator = NULL;
-               ap_device_probe(dev);
-               ap_reset(ap_dev);
-               setup_timer(&ap_dev->timeout, ap_request_timeout,
-                           (unsigned long) ap_dev);
-               ap_scan_bus(NULL);
+               if (!user_set_domain) {
+                       ap_domain_index = -1;
+                       ap_select_domain();
+               }
                init_timer(&ap_config_timer);
                ap_config_timer.function = ap_config_timeout;
                ap_config_timer.data = 0;
                        tasklet_schedule(&ap_tasklet);
                if (ap_thread_flag)
                        rc = ap_poll_thread_start();
-       } else {
-               ap_device_probe(dev);
-               ap_reset(ap_dev);
-               setup_timer(&ap_dev->timeout, ap_request_timeout,
-                           (unsigned long) ap_dev);
        }
+       if (AP_QID_QUEUE(ap_dev->qid) != ap_domain_index) {
+               spin_lock_bh(&ap_dev->lock);
+               ap_dev->qid = AP_MKQID(AP_QID_DEVICE(ap_dev->qid),
+                                      ap_domain_index);
+               spin_unlock_bh(&ap_dev->lock);
+       }
+       queue_work(ap_work_queue, &ap_config_work);
 
        return rc;
 }
                        spin_lock_bh(&ap_dev->lock);
                        if (rc || ap_dev->unregistered) {
                                spin_unlock_bh(&ap_dev->lock);
+                               if (ap_dev->unregistered)
+                                       i--;
                                device_unregister(dev);
                                put_device(dev);
                                continue;
                           ap_domain_index);
                return -EINVAL;
        }
+       /* In resume callback we need to know if the user had set the domain.
+        * If so, we can not just reset it.
+        */
+       if (ap_domain_index >= 0)
+               user_set_domain = 1;
+
        if (ap_instructions_available() != 0) {
                pr_warning("The hardware system does not support "
                           "AP instructions\n");