diff options
Diffstat (limited to 'drivers/mtd/ubi/build.c')
-rw-r--r-- | drivers/mtd/ubi/build.c | 91 |
1 files changed, 17 insertions, 74 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); |