diff options
Diffstat (limited to 'drivers/s390/crypto')
| -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 ed3dcdea7fe..090b32a339c 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)  	/* Poll on the device until all requests are finished. */  	do {  		flags = 0; +		spin_lock_bh(&ap_dev->lock);  		__ap_poll_device(ap_dev, &flags); +		spin_unlock_bh(&ap_dev->lock);  	} while ((flags & 1) || (flags & 2));  	ap_device_remove(dev); @@ -1109,12 +1111,15 @@ static void ap_scan_bus(struct work_struct *unused)  		ap_dev->device.bus = &ap_bus_type;  		ap_dev->device.parent = ap_root_device; -		dev_set_name(&ap_dev->device, "card%02x", -			     AP_QID_DEVICE(ap_dev->qid)); +		if (dev_set_name(&ap_dev->device, "card%02x", +				 AP_QID_DEVICE(ap_dev->qid))) { +			kfree(ap_dev); +			continue; +		}  		ap_dev->device.release = ap_device_release;  		rc = device_register(&ap_dev->device);  		if (rc) { -			kfree(ap_dev); +			put_device(&ap_dev->device);  			continue;  		}  		/* Add device attributes. */ @@ -1407,14 +1412,12 @@ static void ap_reset(struct ap_device *ap_dev)  static int __ap_poll_device(struct ap_device *ap_dev, unsigned long *flags)  { -	spin_lock(&ap_dev->lock);  	if (!ap_dev->unregistered) {  		if (ap_poll_queue(ap_dev, flags))  			ap_dev->unregistered = 1;  		if (ap_dev->reset == AP_RESET_DO)  			ap_reset(ap_dev);  	} -	spin_unlock(&ap_dev->lock);  	return 0;  } @@ -1441,7 +1444,9 @@ static void ap_poll_all(unsigned long dummy)  		flags = 0;  		spin_lock(&ap_device_list_lock);  		list_for_each_entry(ap_dev, &ap_device_list, list) { +			spin_lock(&ap_dev->lock);  			__ap_poll_device(ap_dev, &flags); +			spin_unlock(&ap_dev->lock);  		}  		spin_unlock(&ap_device_list_lock);  	} while (flags & 1); @@ -1487,7 +1492,9 @@ static int ap_poll_thread(void *data)  		flags = 0;  		spin_lock_bh(&ap_device_list_lock);  		list_for_each_entry(ap_dev, &ap_device_list, list) { +			spin_lock(&ap_dev->lock);  			__ap_poll_device(ap_dev, &flags); +			spin_unlock(&ap_dev->lock);  		}  		spin_unlock_bh(&ap_device_list_lock);  	}  |