diff options
-rw-r--r-- | drivers/usb/gadget/function/f_accessory.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/usb/gadget/function/f_accessory.c b/drivers/usb/gadget/function/f_accessory.c index ab3e47c1083e..0cae99243080 100644 --- a/drivers/usb/gadget/function/f_accessory.c +++ b/drivers/usb/gadget/function/f_accessory.c | |||
@@ -1349,6 +1349,9 @@ static int acc_setup(void) | |||
1349 | struct acc_dev *dev; | 1349 | struct acc_dev *dev; |
1350 | int ret; | 1350 | int ret; |
1351 | 1351 | ||
1352 | if (kref_read(&ref->kref)) | ||
1353 | return -EBUSY; | ||
1354 | |||
1352 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 1355 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
1353 | if (!dev) | 1356 | if (!dev) |
1354 | return -ENOMEM; | 1357 | return -ENOMEM; |
@@ -1367,16 +1370,21 @@ static int acc_setup(void) | |||
1367 | INIT_WORK(&dev->sendstring_work, acc_sendstring_work); | 1370 | INIT_WORK(&dev->sendstring_work, acc_sendstring_work); |
1368 | 1371 | ||
1369 | dev->ref = ref; | 1372 | dev->ref = ref; |
1370 | kref_init(&ref->kref); | 1373 | if (cmpxchg_relaxed(&ref->acc_dev, NULL, dev)) { |
1371 | ref->acc_dev = dev; | 1374 | ret = -EBUSY; |
1375 | goto err_free_dev; | ||
1376 | } | ||
1372 | 1377 | ||
1373 | ret = misc_register(&acc_device); | 1378 | ret = misc_register(&acc_device); |
1374 | if (ret) | 1379 | if (ret) |
1375 | goto err; | 1380 | goto err_zap_ptr; |
1376 | 1381 | ||
1382 | kref_init(&ref->kref); | ||
1377 | return 0; | 1383 | return 0; |
1378 | 1384 | ||
1379 | err: | 1385 | err_zap_ptr: |
1386 | ref->acc_dev = NULL; | ||
1387 | err_free_dev: | ||
1380 | kfree(dev); | 1388 | kfree(dev); |
1381 | pr_err("USB accessory gadget driver failed to initialize\n"); | 1389 | pr_err("USB accessory gadget driver failed to initialize\n"); |
1382 | return ret; | 1390 | return ret; |