aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/crypto/ap_bus.c40
1 files changed, 29 insertions, 11 deletions
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index 090b32a339c6..1294876bf7b4 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -60,6 +60,7 @@ static int ap_device_probe(struct device *dev);
60static void ap_interrupt_handler(void *unused1, void *unused2); 60static void ap_interrupt_handler(void *unused1, void *unused2);
61static void ap_reset(struct ap_device *ap_dev); 61static void ap_reset(struct ap_device *ap_dev);
62static void ap_config_timeout(unsigned long ptr); 62static void ap_config_timeout(unsigned long ptr);
63static int ap_select_domain(void);
63 64
64/* 65/*
65 * Module description. 66 * Module description.
@@ -109,6 +110,10 @@ static unsigned long long poll_timeout = 250000;
109 110
110/* Suspend flag */ 111/* Suspend flag */
111static int ap_suspend_flag; 112static int ap_suspend_flag;
113/* Flag to check if domain was set through module parameter domain=. This is
114 * important when supsend and resume is done in a z/VM environment where the
115 * domain might change. */
116static int user_set_domain = 0;
112static struct bus_type ap_bus_type; 117static struct bus_type ap_bus_type;
113 118
114/** 119/**
@@ -643,6 +648,7 @@ static int ap_bus_suspend(struct device *dev, pm_message_t state)
643 destroy_workqueue(ap_work_queue); 648 destroy_workqueue(ap_work_queue);
644 ap_work_queue = NULL; 649 ap_work_queue = NULL;
645 } 650 }
651
646 tasklet_disable(&ap_tasklet); 652 tasklet_disable(&ap_tasklet);
647 } 653 }
648 /* Poll on the device until all requests are finished. */ 654 /* Poll on the device until all requests are finished. */
@@ -653,7 +659,10 @@ static int ap_bus_suspend(struct device *dev, pm_message_t state)
653 spin_unlock_bh(&ap_dev->lock); 659 spin_unlock_bh(&ap_dev->lock);
654 } while ((flags & 1) || (flags & 2)); 660 } while ((flags & 1) || (flags & 2));
655 661
656 ap_device_remove(dev); 662 spin_lock_bh(&ap_dev->lock);
663 ap_dev->unregistered = 1;
664 spin_unlock_bh(&ap_dev->lock);
665
657 return 0; 666 return 0;
658} 667}
659 668
@@ -666,11 +675,10 @@ static int ap_bus_resume(struct device *dev)
666 ap_suspend_flag = 0; 675 ap_suspend_flag = 0;
667 if (!ap_interrupts_available()) 676 if (!ap_interrupts_available())
668 ap_interrupt_indicator = NULL; 677 ap_interrupt_indicator = NULL;
669 ap_device_probe(dev); 678 if (!user_set_domain) {
670 ap_reset(ap_dev); 679 ap_domain_index = -1;
671 setup_timer(&ap_dev->timeout, ap_request_timeout, 680 ap_select_domain();
672 (unsigned long) ap_dev); 681 }
673 ap_scan_bus(NULL);
674 init_timer(&ap_config_timer); 682 init_timer(&ap_config_timer);
675 ap_config_timer.function = ap_config_timeout; 683 ap_config_timer.function = ap_config_timeout;
676 ap_config_timer.data = 0; 684 ap_config_timer.data = 0;
@@ -686,12 +694,14 @@ static int ap_bus_resume(struct device *dev)
686 tasklet_schedule(&ap_tasklet); 694 tasklet_schedule(&ap_tasklet);
687 if (ap_thread_flag) 695 if (ap_thread_flag)
688 rc = ap_poll_thread_start(); 696 rc = ap_poll_thread_start();
689 } else {
690 ap_device_probe(dev);
691 ap_reset(ap_dev);
692 setup_timer(&ap_dev->timeout, ap_request_timeout,
693 (unsigned long) ap_dev);
694 } 697 }
698 if (AP_QID_QUEUE(ap_dev->qid) != ap_domain_index) {
699 spin_lock_bh(&ap_dev->lock);
700 ap_dev->qid = AP_MKQID(AP_QID_DEVICE(ap_dev->qid),
701 ap_domain_index);
702 spin_unlock_bh(&ap_dev->lock);
703 }
704 queue_work(ap_work_queue, &ap_config_work);
695 705
696 return rc; 706 return rc;
697} 707}
@@ -1079,6 +1089,8 @@ static void ap_scan_bus(struct work_struct *unused)
1079 spin_lock_bh(&ap_dev->lock); 1089 spin_lock_bh(&ap_dev->lock);
1080 if (rc || ap_dev->unregistered) { 1090 if (rc || ap_dev->unregistered) {
1081 spin_unlock_bh(&ap_dev->lock); 1091 spin_unlock_bh(&ap_dev->lock);
1092 if (ap_dev->unregistered)
1093 i--;
1082 device_unregister(dev); 1094 device_unregister(dev);
1083 put_device(dev); 1095 put_device(dev);
1084 continue; 1096 continue;
@@ -1586,6 +1598,12 @@ int __init ap_module_init(void)
1586 ap_domain_index); 1598 ap_domain_index);
1587 return -EINVAL; 1599 return -EINVAL;
1588 } 1600 }
1601 /* In resume callback we need to know if the user had set the domain.
1602 * If so, we can not just reset it.
1603 */
1604 if (ap_domain_index >= 0)
1605 user_set_domain = 1;
1606
1589 if (ap_instructions_available() != 0) { 1607 if (ap_instructions_available() != 0) {
1590 pr_warning("The hardware system does not support " 1608 pr_warning("The hardware system does not support "
1591 "AP instructions\n"); 1609 "AP instructions\n");