diff options
author | Linus Torvalds | 2017-05-04 19:07:10 -0700 |
---|---|---|
committer | Linus Torvalds | 2017-05-04 19:15:35 -0700 |
commit | af82455f7dbd9dc20244d80d033721b30d22c065 (patch) | |
tree | 3b9246456e82ae116b57834a2f0b4a307a016474 /drivers/mtd | |
parent | 0be75179df5e20306528800fc7c6a504b12b97db (diff) | |
parent | 2a76f89fa58c769241cfc21f2614705591519ae3 (diff) |
Merge tag 'char-misc-4.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver updates from Greg KH:
"Here is the big set of new char/misc driver drivers and features for
4.12-rc1.
There's lots of new drivers added this time around, new firmware
drivers from Google, more auxdisplay drivers, extcon drivers, fpga
drivers, and a bunch of other driver updates. Nothing major, except if
you happen to have the hardware for these drivers, and then you will
be happy :)
All of these have been in linux-next for a while with no reported
issues"
* tag 'char-misc-4.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (136 commits)
firmware: google memconsole: Fix return value check in platform_memconsole_init()
firmware: Google VPD: Fix return value check in vpd_platform_init()
goldfish_pipe: fix build warning about using too much stack.
goldfish_pipe: An implementation of more parallel pipe
fpga fr br: update supported version numbers
fpga: region: release FPGA region reference in error path
fpga altera-hps2fpga: disable/unprepare clock on error in alt_fpga_bridge_probe()
mei: drop the TODO from samples
firmware: Google VPD sysfs driver
firmware: Google VPD: import lib_vpd source files
misc: lkdtm: Add volatile to intentional NULL pointer reference
eeprom: idt_89hpesx: Add OF device ID table
misc: ds1682: Add OF device ID table
misc: tsl2550: Add OF device ID table
w1: Remove unneeded use of assert() and remove w1_log.h
w1: Use kernel common min() implementation
uio_mf624: Align memory regions to page size and set correct offsets
uio_mf624: Refactor memory info initialization
uio: Allow handling of non page-aligned memory regions
hangcheck-timer: Fix typo in comment
...
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/ubi/build.c | 91 | ||||
-rw-r--r-- | drivers/mtd/ubi/vmt.c | 49 |
2 files changed, 33 insertions, 107 deletions
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 77513195f50e..8bae3731d039 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c @@ -421,41 +421,6 @@ static void dev_release(struct device *dev) } /** - * ubi_sysfs_init - initialize sysfs for an UBI device. - * @ubi: UBI device description object - * @ref: set to %1 on exit in case of failure if a reference to @ubi->dev was - * taken - * - * This function returns zero in case of success and a negative error code in - * case of failure. - */ -static int ubi_sysfs_init(struct ubi_device *ubi, int *ref) -{ - int err; - - ubi->dev.release = dev_release; - ubi->dev.devt = ubi->cdev.dev; - ubi->dev.class = &ubi_class; - ubi->dev.groups = ubi_dev_groups; - dev_set_name(&ubi->dev, UBI_NAME_STR"%d", ubi->ubi_num); - err = device_register(&ubi->dev); - if (err) - return err; - - *ref = 1; - return 0; -} - -/** - * ubi_sysfs_close - close sysfs for an UBI device. - * @ubi: UBI device description object - */ -static void ubi_sysfs_close(struct ubi_device *ubi) -{ - device_unregister(&ubi->dev); -} - -/** * kill_volumes - destroy all user volumes. * @ubi: UBI device description object */ @@ -471,27 +436,19 @@ static void kill_volumes(struct ubi_device *ubi) /** * uif_init - initialize user interfaces for an UBI device. * @ubi: UBI device description object - * @ref: set to %1 on exit in case of failure if a reference to @ubi->dev was - * taken, otherwise set to %0 * * This function initializes various user interfaces for an UBI device. If the * initialization fails at an early stage, this function frees all the - * resources it allocated, returns an error, and @ref is set to %0. However, - * if the initialization fails after the UBI device was registered in the - * driver core subsystem, this function takes a reference to @ubi->dev, because - * otherwise the release function ('dev_release()') would free whole @ubi - * object. The @ref argument is set to %1 in this case. The caller has to put - * this reference. + * resources it allocated, returns an error. * * This function returns zero in case of success and a negative error code in * case of failure. */ -static int uif_init(struct ubi_device *ubi, int *ref) +static int uif_init(struct ubi_device *ubi) { int i, err; dev_t dev; - *ref = 0; sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num); /* @@ -508,20 +465,17 @@ static int uif_init(struct ubi_device *ubi, int *ref) return err; } + ubi->dev.devt = dev; + ubi_assert(MINOR(dev) == 0); cdev_init(&ubi->cdev, &ubi_cdev_operations); dbg_gen("%s major is %u", ubi->ubi_name, MAJOR(dev)); ubi->cdev.owner = THIS_MODULE; - err = cdev_add(&ubi->cdev, dev, 1); - if (err) { - ubi_err(ubi, "cannot add character device"); - goto out_unreg; - } - - err = ubi_sysfs_init(ubi, ref); + dev_set_name(&ubi->dev, UBI_NAME_STR "%d", ubi->ubi_num); + err = cdev_device_add(&ubi->cdev, &ubi->dev); if (err) - goto out_sysfs; + goto out_unreg; for (i = 0; i < ubi->vtbl_slots; i++) if (ubi->volumes[i]) { @@ -536,11 +490,7 @@ static int uif_init(struct ubi_device *ubi, int *ref) out_volumes: kill_volumes(ubi); -out_sysfs: - if (*ref) - get_device(&ubi->dev); - ubi_sysfs_close(ubi); - cdev_del(&ubi->cdev); + cdev_device_del(&ubi->cdev, &ubi->dev); out_unreg: unregister_chrdev_region(ubi->cdev.dev, ubi->vtbl_slots + 1); ubi_err(ubi, "cannot initialize UBI %s, error %d", @@ -559,8 +509,7 @@ out_unreg: static void uif_close(struct ubi_device *ubi) { kill_volumes(ubi); - ubi_sysfs_close(ubi); - cdev_del(&ubi->cdev); + cdev_device_del(&ubi->cdev, &ubi->dev); unregister_chrdev_region(ubi->cdev.dev, ubi->vtbl_slots + 1); } @@ -857,7 +806,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset, int max_beb_per1024) { struct ubi_device *ubi; - int i, err, ref = 0; + int i, err; if (max_beb_per1024 < 0 || max_beb_per1024 > MAX_MTD_UBI_BEB_LIMIT) return -EINVAL; @@ -919,6 +868,11 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, if (!ubi) return -ENOMEM; + device_initialize(&ubi->dev); + ubi->dev.release = dev_release; + ubi->dev.class = &ubi_class; + ubi->dev.groups = ubi_dev_groups; + ubi->mtd = mtd; ubi->ubi_num = ubi_num; ubi->vid_hdr_offset = vid_hdr_offset; @@ -995,7 +949,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, /* Make device "available" before it becomes accessible via sysfs */ ubi_devices[ubi_num] = ubi; - err = uif_init(ubi, &ref); + err = uif_init(ubi); if (err) goto out_detach; @@ -1045,8 +999,6 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, out_debugfs: ubi_debugfs_exit_dev(ubi); out_uif: - get_device(&ubi->dev); - ubi_assert(ref); uif_close(ubi); out_detach: ubi_devices[ubi_num] = NULL; @@ -1056,10 +1008,7 @@ out_detach: out_free: vfree(ubi->peb_buf); vfree(ubi->fm_buf); - if (ref) - put_device(&ubi->dev); - else - kfree(ubi); + put_device(&ubi->dev); return err; } @@ -1120,12 +1069,6 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) if (ubi->bgt_thread) kthread_stop(ubi->bgt_thread); - /* - * Get a reference to the device in order to prevent 'dev_release()' - * from freeing the @ubi object. - */ - get_device(&ubi->dev); - ubi_debugfs_exit_dev(ubi); uif_close(ubi); diff --git a/drivers/mtd/ubi/vmt.c b/drivers/mtd/ubi/vmt.c index 7ac78c13dd1c..85237cf661f9 100644 --- a/drivers/mtd/ubi/vmt.c +++ b/drivers/mtd/ubi/vmt.c @@ -155,11 +155,10 @@ static void vol_release(struct device *dev) */ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) { - int i, err, vol_id = req->vol_id, do_free = 1; + int i, err, vol_id = req->vol_id; struct ubi_volume *vol; struct ubi_vtbl_record vtbl_rec; struct ubi_eba_table *eba_tbl = NULL; - dev_t dev; if (ubi->ro_mode) return -EROFS; @@ -168,6 +167,12 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) if (!vol) return -ENOMEM; + device_initialize(&vol->dev); + vol->dev.release = vol_release; + vol->dev.parent = &ubi->dev; + vol->dev.class = &ubi_class; + vol->dev.groups = volume_dev_groups; + spin_lock(&ubi->volumes_lock); if (vol_id == UBI_VOL_NUM_AUTO) { /* Find unused volume ID */ @@ -268,24 +273,13 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req) /* Register character device for the volume */ cdev_init(&vol->cdev, &ubi_vol_cdev_operations); vol->cdev.owner = THIS_MODULE; - dev = MKDEV(MAJOR(ubi->cdev.dev), vol_id + 1); - err = cdev_add(&vol->cdev, dev, 1); - if (err) { - ubi_err(ubi, "cannot add character device"); - goto out_mapping; - } - - vol->dev.release = vol_release; - vol->dev.parent = &ubi->dev; - vol->dev.devt = dev; - vol->dev.class = &ubi_class; - vol->dev.groups = volume_dev_groups; + vol->dev.devt = MKDEV(MAJOR(ubi->cdev.dev), vol_id + 1); dev_set_name(&vol->dev, "%s_%d", ubi->ubi_name, vol->vol_id); - err = device_register(&vol->dev); + err = cdev_device_add(&vol->cdev, &vol->dev); if (err) { - ubi_err(ubi, "cannot register device"); - goto out_cdev; + ubi_err(ubi, "cannot add device"); + goto out_mapping; } /* Fill volume table record */ @@ -318,28 +312,17 @@ out_sysfs: * We have registered our device, we should not free the volume * description object in this function in case of an error - it is * freed by the release function. - * - * Get device reference to prevent the release function from being - * called just after sysfs has been closed. */ - do_free = 0; - get_device(&vol->dev); - device_unregister(&vol->dev); -out_cdev: - cdev_del(&vol->cdev); + cdev_device_del(&vol->cdev, &vol->dev); out_mapping: - if (do_free) - ubi_eba_destroy_table(eba_tbl); + ubi_eba_destroy_table(eba_tbl); out_acc: spin_lock(&ubi->volumes_lock); ubi->rsvd_pebs -= vol->reserved_pebs; ubi->avail_pebs += vol->reserved_pebs; out_unlock: spin_unlock(&ubi->volumes_lock); - if (do_free) - kfree(vol); - else - put_device(&vol->dev); + put_device(&vol->dev); ubi_err(ubi, "cannot create volume %d, error %d", vol_id, err); return err; } @@ -391,8 +374,8 @@ int ubi_remove_volume(struct ubi_volume_desc *desc, int no_vtbl) goto out_err; } - cdev_del(&vol->cdev); - device_unregister(&vol->dev); + cdev_device_del(&vol->cdev, &vol->dev); + put_device(&vol->dev); spin_lock(&ubi->volumes_lock); ubi->rsvd_pebs -= reserved_pebs; |