]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/mtd/mtdcore.c
Merge branch 'akpm-current/current'
[karo-tx-linux.git] / drivers / mtd / mtdcore.c
index 2dfb291a47c6da6e64caa1788f1329305658b9c5..a9a15c22ef24649ff4ef82385a1128dfef8d7818 100644 (file)
@@ -387,6 +387,14 @@ int add_mtd_device(struct mtd_info *mtd)
        struct mtd_notifier *not;
        int i, error;
 
+       /*
+        * May occur, for instance, on buggy drivers which call
+        * mtd_device_parse_register() multiple times on the same master MTD,
+        * especially with CONFIG_MTD_PARTITIONED_MASTER=y.
+        */
+       if (WARN_ONCE(mtd->backing_dev_info, "MTD already registered\n"))
+               return -EEXIST;
+
        mtd->backing_dev_info = &mtd_bdi;
 
        BUG_ON(mtd->writesize == 0);
@@ -418,6 +426,15 @@ int add_mtd_device(struct mtd_info *mtd)
        mtd->erasesize_mask = (1 << mtd->erasesize_shift) - 1;
        mtd->writesize_mask = (1 << mtd->writesize_shift) - 1;
 
+       if (mtd->dev.parent) {
+               if (!mtd->owner && mtd->dev.parent->driver)
+                       mtd->owner = mtd->dev.parent->driver->owner;
+               if (!mtd->name)
+                       mtd->name = dev_name(mtd->dev.parent);
+       } else {
+               pr_debug("mtd device won't show a device symlink in sysfs\n");
+       }
+
        /* Some chips always power up locked. Unlock them now */
        if ((mtd->flags & MTD_WRITEABLE) && (mtd->flags & MTD_POWERUP_LOCK)) {
                error = mtd_unlock(mtd, 0, mtd->size);
@@ -430,7 +447,7 @@ int add_mtd_device(struct mtd_info *mtd)
        }
 
        /* Caller should have set dev.parent to match the
-        * physical device.
+        * physical device, if appropriate.
         */
        mtd->dev.type = &mtd_devtype;
        mtd->dev.class = &mtd_class;
@@ -579,9 +596,17 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
                else
                        ret = nr_parts;
        }
+       /* Didn't come up with either parsed OR fallback partitions */
+       if (ret < 0) {
+               pr_info("mtd: failed to find partitions; one or more parsers reports errors (%d)\n",
+                       ret);
+               /* Don't abort on errors; we can still use unpartitioned MTD */
+               ret = 0;
+       }
 
-       if (ret >= 0)
-               ret = mtd_add_device_partitions(mtd, real_parts, ret);
+       ret = mtd_add_device_partitions(mtd, real_parts, ret);
+       if (ret)
+               goto out;
 
        /*
         * FIXME: some drivers unfortunately call this function more than once.
@@ -591,11 +616,13 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
         * does cause problems with parse_mtd_partitions() above (e.g.,
         * cmdlineparts will register partitions more than once).
         */
+       WARN_ONCE(mtd->reboot_notifier.notifier_call, "MTD already registered\n");
        if (mtd->_reboot && !mtd->reboot_notifier.notifier_call) {
                mtd->reboot_notifier.notifier_call = mtd_reboot_notifier;
                register_reboot_notifier(&mtd->reboot_notifier);
        }
 
+out:
        kfree(real_parts);
        return ret;
 }
@@ -1300,6 +1327,7 @@ static void __exit cleanup_mtd(void)
                remove_proc_entry("mtd", NULL);
        class_unregister(&mtd_class);
        bdi_destroy(&mtd_bdi);
+       idr_destroy(&mtd_idr);
 }
 
 module_init(init_mtd);