summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/gadget/function/f_accessory.c16
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 4aa4a57d0fc5..b48d75657012 100644
--- a/drivers/usb/gadget/function/f_accessory.c
+++ b/drivers/usb/gadget/function/f_accessory.c
@@ -1259,6 +1259,9 @@ static int acc_setup(void)
struct acc_dev *dev;
int ret;
+ if (kref_read(&ref->kref))
+ return -EBUSY;
+
dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev)
return -ENOMEM;
@@ -1275,16 +1278,21 @@ static int acc_setup(void)
INIT_WORK(&dev->hid_work, acc_hid_work);
dev->ref = ref;
- kref_init(&ref->kref);
- ref->acc_dev = dev;
+ if (cmpxchg_relaxed(&ref->acc_dev, NULL, dev)) {
+ ret = -EBUSY;
+ goto err_free_dev;
+ }
ret = misc_register(&acc_device);
if (ret)
- goto err;
+ goto err_zap_ptr;
+ kref_init(&ref->kref);
return 0;
-err:
+err_zap_ptr:
+ ref->acc_dev = NULL;
+err_free_dev:
kfree(dev);
pr_err("USB accessory gadget driver failed to initialize\n");
return ret;