diff options
Diffstat (limited to 'drivers/s390/crypto/ap_bus.c')
-rw-r--r-- | drivers/s390/crypto/ap_bus.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index ed3dcdea7fe1..090b32a339c6 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c | |||
@@ -648,7 +648,9 @@ static int ap_bus_suspend(struct device *dev, pm_message_t state) | |||
648 | /* Poll on the device until all requests are finished. */ | 648 | /* Poll on the device until all requests are finished. */ |
649 | do { | 649 | do { |
650 | flags = 0; | 650 | flags = 0; |
651 | spin_lock_bh(&ap_dev->lock); | ||
651 | __ap_poll_device(ap_dev, &flags); | 652 | __ap_poll_device(ap_dev, &flags); |
653 | spin_unlock_bh(&ap_dev->lock); | ||
652 | } while ((flags & 1) || (flags & 2)); | 654 | } while ((flags & 1) || (flags & 2)); |
653 | 655 | ||
654 | ap_device_remove(dev); | 656 | ap_device_remove(dev); |
@@ -1109,12 +1111,15 @@ static void ap_scan_bus(struct work_struct *unused) | |||
1109 | 1111 | ||
1110 | ap_dev->device.bus = &ap_bus_type; | 1112 | ap_dev->device.bus = &ap_bus_type; |
1111 | ap_dev->device.parent = ap_root_device; | 1113 | ap_dev->device.parent = ap_root_device; |
1112 | dev_set_name(&ap_dev->device, "card%02x", | 1114 | if (dev_set_name(&ap_dev->device, "card%02x", |
1113 | AP_QID_DEVICE(ap_dev->qid)); | 1115 | AP_QID_DEVICE(ap_dev->qid))) { |
1116 | kfree(ap_dev); | ||
1117 | continue; | ||
1118 | } | ||
1114 | ap_dev->device.release = ap_device_release; | 1119 | ap_dev->device.release = ap_device_release; |
1115 | rc = device_register(&ap_dev->device); | 1120 | rc = device_register(&ap_dev->device); |
1116 | if (rc) { | 1121 | if (rc) { |
1117 | kfree(ap_dev); | 1122 | put_device(&ap_dev->device); |
1118 | continue; | 1123 | continue; |
1119 | } | 1124 | } |
1120 | /* Add device attributes. */ | 1125 | /* Add device attributes. */ |
@@ -1407,14 +1412,12 @@ static void ap_reset(struct ap_device *ap_dev) | |||
1407 | 1412 | ||
1408 | static int __ap_poll_device(struct ap_device *ap_dev, unsigned long *flags) | 1413 | static int __ap_poll_device(struct ap_device *ap_dev, unsigned long *flags) |
1409 | { | 1414 | { |
1410 | spin_lock(&ap_dev->lock); | ||
1411 | if (!ap_dev->unregistered) { | 1415 | if (!ap_dev->unregistered) { |
1412 | if (ap_poll_queue(ap_dev, flags)) | 1416 | if (ap_poll_queue(ap_dev, flags)) |
1413 | ap_dev->unregistered = 1; | 1417 | ap_dev->unregistered = 1; |
1414 | if (ap_dev->reset == AP_RESET_DO) | 1418 | if (ap_dev->reset == AP_RESET_DO) |
1415 | ap_reset(ap_dev); | 1419 | ap_reset(ap_dev); |
1416 | } | 1420 | } |
1417 | spin_unlock(&ap_dev->lock); | ||
1418 | return 0; | 1421 | return 0; |
1419 | } | 1422 | } |
1420 | 1423 | ||
@@ -1441,7 +1444,9 @@ static void ap_poll_all(unsigned long dummy) | |||
1441 | flags = 0; | 1444 | flags = 0; |
1442 | spin_lock(&ap_device_list_lock); | 1445 | spin_lock(&ap_device_list_lock); |
1443 | list_for_each_entry(ap_dev, &ap_device_list, list) { | 1446 | list_for_each_entry(ap_dev, &ap_device_list, list) { |
1447 | spin_lock(&ap_dev->lock); | ||
1444 | __ap_poll_device(ap_dev, &flags); | 1448 | __ap_poll_device(ap_dev, &flags); |
1449 | spin_unlock(&ap_dev->lock); | ||
1445 | } | 1450 | } |
1446 | spin_unlock(&ap_device_list_lock); | 1451 | spin_unlock(&ap_device_list_lock); |
1447 | } while (flags & 1); | 1452 | } while (flags & 1); |
@@ -1487,7 +1492,9 @@ static int ap_poll_thread(void *data) | |||
1487 | flags = 0; | 1492 | flags = 0; |
1488 | spin_lock_bh(&ap_device_list_lock); | 1493 | spin_lock_bh(&ap_device_list_lock); |
1489 | list_for_each_entry(ap_dev, &ap_device_list, list) { | 1494 | list_for_each_entry(ap_dev, &ap_device_list, list) { |
1495 | spin_lock(&ap_dev->lock); | ||
1490 | __ap_poll_device(ap_dev, &flags); | 1496 | __ap_poll_device(ap_dev, &flags); |
1497 | spin_unlock(&ap_dev->lock); | ||
1491 | } | 1498 | } |
1492 | spin_unlock_bh(&ap_device_list_lock); | 1499 | spin_unlock_bh(&ap_device_list_lock); |
1493 | } | 1500 | } |