comment "User Modules And Translation Layers"
 
-config MTD_CHAR
-       tristate "Direct char device access to MTD devices"
-       help
-         This provides a character device for each MTD device present in
-         the system, allowing the user to read and write directly to the
-         memory chips, and also use ioctl() to obtain information about
-         the device, or to erase parts of it.
-
-config HAVE_MTD_OTP
-       bool
-       help
-         Enable access to OTP regions using MTD_CHAR.
-
 config MTD_BLKDEVS
        tristate "Common interface to block layer for MTD 'translation layers'"
        depends on BLOCK
 
 
 # Core functionality.
 obj-$(CONFIG_MTD)              += mtd.o
-mtd-y                          := mtdcore.o mtdsuper.o mtdconcat.o mtdpart.o
+mtd-y                          := mtdcore.o mtdsuper.o mtdconcat.o mtdpart.o mtdchar.o
 
 obj-$(CONFIG_MTD_OF_PARTS)     += ofpart.o
 obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o
 obj-$(CONFIG_MTD_BCM47XX_PARTS)        += bcm47xxpart.o
 
 # 'Users' - code which presents functionality to userspace.
-obj-$(CONFIG_MTD_CHAR)         += mtdchar.o
 obj-$(CONFIG_MTD_BLKDEVS)      += mtd_blkdevs.o
 obj-$(CONFIG_MTD_BLOCK)                += mtdblock.o
 obj-$(CONFIG_MTD_BLOCK_RO)     += mtdblock_ro.o
 
 config MTD_OTP
        bool "Protection Registers aka one-time programmable (OTP) bits"
        depends on MTD_CFI_ADV_OPTIONS
-       select HAVE_MTD_OTP
        default n
        help
          This enables support for reading, writing and locking so called
 
 config MTD_DATAFLASH_OTP
        bool "DataFlash OTP support (Security Register)"
        depends on MTD_DATAFLASH
-       select HAVE_MTD_OTP
        help
          Newer DataFlash chips (revisions C and D) support 128 bytes of
          one-time-programmable (OTP) data.  The first half may be written
 
 
 #include <asm/uaccess.h>
 
+#include "mtdcore.h"
+
 static DEFINE_MUTEX(mtd_mutex);
 
 /*
        wake_up((wait_queue_head_t *)instr->priv);
 }
 
-#ifdef CONFIG_HAVE_MTD_OTP
 static int otp_select_filemode(struct mtd_file_info *mfi, int mode)
 {
        struct mtd_info *mtd = mfi->mtd;
 
        return 0;
 }
-#else
-# define otp_select_filemode(f,m)      -EOPNOTSUPP
-#endif
 
 static int mtdchar_writeoob(struct file *file, struct mtd_info *mtd,
        uint64_t start, uint32_t length, void __user *ptr,
                break;
        }
 
-#ifdef CONFIG_HAVE_MTD_OTP
        case OTPSELECT:
        {
                int mode;
                ret = mtd_lock_user_prot_reg(mtd, oinfo.start, oinfo.length);
                break;
        }
-#endif
 
        /* This ioctl is being deprecated - it truncates the ECC layout */
        case ECCGETLAYOUT:
 };
 MODULE_ALIAS_FS("mtd_inodefs");
 
-static int __init init_mtdchar(void)
+int __init init_mtdchar(void)
 {
        int ret;
 
        return ret;
 }
 
-static void __exit cleanup_mtdchar(void)
+void __exit cleanup_mtdchar(void)
 {
        unregister_filesystem(&mtd_inodefs_type);
        __unregister_chrdev(MTD_CHAR_MAJOR, 0, 1 << MINORBITS, "mtd");
 }
 
-module_init(init_mtdchar);
-module_exit(cleanup_mtdchar);
-
-MODULE_ALIAS_CHARDEV_MAJOR(MTD_CHAR_MAJOR);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
-MODULE_DESCRIPTION("Direct character-device access to MTD devices");
 MODULE_ALIAS_CHARDEV_MAJOR(MTD_CHAR_MAJOR);
 
 #include <linux/mtd/partitions.h>
 
 #include "mtdcore.h"
+
 /*
  * backing device capabilities for non-mappable devices (such as NAND flash)
  * - permits private mappings, copies are taken of the data
 static LIST_HEAD(mtd_notifiers);
 
 
-#if defined(CONFIG_MTD_CHAR) || defined(CONFIG_MTD_CHAR_MODULE)
 #define MTD_DEVT(index) MKDEV(MTD_CHAR_MAJOR, (index)*2)
-#else
-#define MTD_DEVT(index) 0
-#endif
 
 /* REVISIT once MTD uses the driver model better, whoever allocates
  * the mtd_info will probably want to use the release() hook...
 
        proc_mtd = proc_create("mtd", 0, NULL, &mtd_proc_ops);
 
+       ret = init_mtdchar();
+       if (ret)
+               goto out_procfs;
+
        return 0;
 
+out_procfs:
+       if (proc_mtd)
+               remove_proc_entry("mtd", NULL);
 err_bdi3:
        bdi_destroy(&mtd_bdi_ro_mappable);
 err_bdi2:
 
 static void __exit cleanup_mtd(void)
 {
+       cleanup_mtdchar();
        if (proc_mtd)
                remove_proc_entry("mtd", NULL);
        class_unregister(&mtd_class);
 
 /*
- * These are exported solely for the purpose of mtd_blkdevs.c. You
- * should not use them for _anything_ else.
+ * These are exported solely for the purpose of mtd_blkdevs.c and mtdchar.c.
+ * You should not use them for _anything_ else.
  */
 
 extern struct mutex mtd_table_mutex;
                         struct mtd_partition **pparts,
                         struct mtd_part_parser_data *data);
 
+int __init init_mtdchar(void);
+void __exit cleanup_mtdchar(void);
+
 #define mtd_for_each_device(mtd)                       \
        for ((mtd) = __mtd_next_device(0);              \
             (mtd) != NULL;                             \
 
 
 config MTD_ONENAND_OTP
        bool "OneNAND OTP Support"
-       select HAVE_MTD_OTP
        help
          One Block of the NAND Flash Array memory is reserved as
          a One-Time Programmable Block memory area.