drm/vc4: add extcon hdmi connection uevent
[platform/kernel/linux-rpi.git] / drivers / block / brd.c
index 58ec167..530b312 100644 (file)
@@ -373,10 +373,22 @@ static int brd_alloc(int i)
        struct gendisk *disk;
        char buf[DISK_NAME_LEN];
 
+       mutex_lock(&brd_devices_mutex);
+       list_for_each_entry(brd, &brd_devices, brd_list) {
+               if (brd->brd_number == i) {
+                       mutex_unlock(&brd_devices_mutex);
+                       return -EEXIST;
+               }
+       }
        brd = kzalloc(sizeof(*brd), GFP_KERNEL);
-       if (!brd)
+       if (!brd) {
+               mutex_unlock(&brd_devices_mutex);
                return -ENOMEM;
+       }
        brd->brd_number         = i;
+       list_add_tail(&brd->brd_list, &brd_devices);
+       mutex_unlock(&brd_devices_mutex);
+
        spin_lock_init(&brd->brd_lock);
        INIT_RADIX_TREE(&brd->brd_pages, GFP_ATOMIC);
 
@@ -411,37 +423,30 @@ static int brd_alloc(int i)
        blk_queue_flag_set(QUEUE_FLAG_NONROT, disk->queue);
        blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, disk->queue);
        add_disk(disk);
-       list_add_tail(&brd->brd_list, &brd_devices);
 
        return 0;
 
 out_free_dev:
+       mutex_lock(&brd_devices_mutex);
+       list_del(&brd->brd_list);
+       mutex_unlock(&brd_devices_mutex);
        kfree(brd);
        return -ENOMEM;
 }
 
 static void brd_probe(dev_t dev)
 {
-       int i = MINOR(dev) / max_part;
-       struct brd_device *brd;
-
-       mutex_lock(&brd_devices_mutex);
-       list_for_each_entry(brd, &brd_devices, brd_list) {
-               if (brd->brd_number == i)
-                       goto out_unlock;
-       }
-
-       brd_alloc(i);
-out_unlock:
-       mutex_unlock(&brd_devices_mutex);
+       brd_alloc(MINOR(dev) / max_part);
 }
 
 static void brd_del_one(struct brd_device *brd)
 {
-       list_del(&brd->brd_list);
        del_gendisk(brd->brd_disk);
        blk_cleanup_disk(brd->brd_disk);
        brd_free_pages(brd);
+       mutex_lock(&brd_devices_mutex);
+       list_del(&brd->brd_list);
+       mutex_unlock(&brd_devices_mutex);
        kfree(brd);
 }
 
@@ -491,25 +496,21 @@ static int __init brd_init(void)
 
        brd_debugfs_dir = debugfs_create_dir("ramdisk_pages", NULL);
 
-       mutex_lock(&brd_devices_mutex);
        for (i = 0; i < rd_nr; i++) {
                err = brd_alloc(i);
                if (err)
                        goto out_free;
        }
 
-       mutex_unlock(&brd_devices_mutex);
-
        pr_info("brd: module loaded\n");
        return 0;
 
 out_free:
+       unregister_blkdev(RAMDISK_MAJOR, "ramdisk");
        debugfs_remove_recursive(brd_debugfs_dir);
 
        list_for_each_entry_safe(brd, next, &brd_devices, brd_list)
                brd_del_one(brd);
-       mutex_unlock(&brd_devices_mutex);
-       unregister_blkdev(RAMDISK_MAJOR, "ramdisk");
 
        pr_info("brd: module NOT loaded !!!\n");
        return err;
@@ -519,13 +520,12 @@ static void __exit brd_exit(void)
 {
        struct brd_device *brd, *next;
 
+       unregister_blkdev(RAMDISK_MAJOR, "ramdisk");
        debugfs_remove_recursive(brd_debugfs_dir);
 
        list_for_each_entry_safe(brd, next, &brd_devices, brd_list)
                brd_del_one(brd);
 
-       unregister_blkdev(RAMDISK_MAJOR, "ramdisk");
-
        pr_info("brd: module unloaded\n");
 }