Lines Matching full:mtd
3 * Core registration and callback routines for MTD
32 #include <linux/mtd/mtd.h>
33 #include <linux/mtd/partitions.h>
43 struct mtd_info *mtd = dev_get_drvdata(dev); in mtd_cls_suspend() local
45 return mtd ? mtd_suspend(mtd) : 0; in mtd_cls_suspend()
50 struct mtd_info *mtd = dev_get_drvdata(dev); in mtd_cls_resume() local
52 if (mtd) in mtd_cls_resume()
53 mtd_resume(mtd); in mtd_cls_resume()
64 .name = "mtd",
102 pr_err("MTD:lock_owner is %s, but current is %s\n", in mtd_table_mutex_unlock()
116 pr_err("MTD:lock_owner is %s, but current is %s\n", in mtd_table_assert_mutex_locked()
122 /* REVISIT once MTD uses the driver model better, whoever allocates
127 struct mtd_info *mtd = dev_get_drvdata(dev); in mtd_release() local
128 dev_t index = MTD_DEVT(mtd->index); in mtd_release()
137 struct mtd_info *mtd = dev_get_drvdata(dev); in mtd_type_show() local
140 switch (mtd->type) { in mtd_type_show()
176 struct mtd_info *mtd = dev_get_drvdata(dev); in mtd_flags_show() local
178 return snprintf(buf, PAGE_SIZE, "0x%lx\n", (unsigned long)mtd->flags); in mtd_flags_show()
185 struct mtd_info *mtd = dev_get_drvdata(dev); in mtd_size_show() local
188 (unsigned long long)mtd->size); in mtd_size_show()
195 struct mtd_info *mtd = dev_get_drvdata(dev); in mtd_erasesize_show() local
197 return snprintf(buf, PAGE_SIZE, "%lu\n", (unsigned long)mtd->erasesize); in mtd_erasesize_show()
204 struct mtd_info *mtd = dev_get_drvdata(dev); in mtd_writesize_show() local
206 return snprintf(buf, PAGE_SIZE, "%lu\n", (unsigned long)mtd->writesize); in mtd_writesize_show()
213 struct mtd_info *mtd = dev_get_drvdata(dev); in mtd_subpagesize_show() local
214 unsigned int subpagesize = mtd->writesize >> mtd->subpage_sft; in mtd_subpagesize_show()
223 struct mtd_info *mtd = dev_get_drvdata(dev); in mtd_oobsize_show() local
225 return snprintf(buf, PAGE_SIZE, "%lu\n", (unsigned long)mtd->oobsize); in mtd_oobsize_show()
232 struct mtd_info *mtd = dev_get_drvdata(dev); in mtd_oobavail_show() local
234 return snprintf(buf, PAGE_SIZE, "%u\n", mtd->oobavail); in mtd_oobavail_show()
241 struct mtd_info *mtd = dev_get_drvdata(dev); in mtd_numeraseregions_show() local
243 return snprintf(buf, PAGE_SIZE, "%u\n", mtd->numeraseregions); in mtd_numeraseregions_show()
251 struct mtd_info *mtd = dev_get_drvdata(dev); in mtd_name_show() local
253 return snprintf(buf, PAGE_SIZE, "%s\n", mtd->name); in mtd_name_show()
260 struct mtd_info *mtd = dev_get_drvdata(dev); in mtd_ecc_strength_show() local
262 return snprintf(buf, PAGE_SIZE, "%u\n", mtd->ecc_strength); in mtd_ecc_strength_show()
270 struct mtd_info *mtd = dev_get_drvdata(dev); in mtd_bitflip_threshold_show() local
272 return snprintf(buf, PAGE_SIZE, "%u\n", mtd->bitflip_threshold); in mtd_bitflip_threshold_show()
279 struct mtd_info *mtd = dev_get_drvdata(dev); in mtd_bitflip_threshold_store() local
287 mtd->bitflip_threshold = bitflip_threshold; in mtd_bitflip_threshold_store()
297 struct mtd_info *mtd = dev_get_drvdata(dev); in mtd_ecc_step_size_show() local
299 return snprintf(buf, PAGE_SIZE, "%u\n", mtd->ecc_step_size); in mtd_ecc_step_size_show()
307 struct mtd_info *mtd = dev_get_drvdata(dev); in mtd_ecc_stats_corrected_show() local
308 struct mtd_ecc_stats *ecc_stats = &mtd->ecc_stats; in mtd_ecc_stats_corrected_show()
318 struct mtd_info *mtd = dev_get_drvdata(dev); in mtd_ecc_stats_errors_show() local
319 struct mtd_ecc_stats *ecc_stats = &mtd->ecc_stats; in mtd_ecc_stats_errors_show()
328 struct mtd_info *mtd = dev_get_drvdata(dev); in mtd_badblocks_show() local
329 struct mtd_ecc_stats *ecc_stats = &mtd->ecc_stats; in mtd_badblocks_show()
338 struct mtd_info *mtd = dev_get_drvdata(dev); in mtd_bbtblocks_show() local
339 struct mtd_ecc_stats *ecc_stats = &mtd->ecc_stats; in mtd_bbtblocks_show()
365 ATTRIBUTE_GROUPS(mtd);
368 .name = "mtd",
375 struct mtd_info *mtd = s->private; in mtd_partid_debug_show() local
377 seq_printf(s, "%s\n", mtd->dbg.partid); in mtd_partid_debug_show()
386 struct mtd_info *mtd = s->private; in mtd_partname_debug_show() local
388 seq_printf(s, "%s\n", mtd->dbg.partname); in mtd_partname_debug_show()
397 static void mtd_debugfs_populate(struct mtd_info *mtd) in mtd_debugfs_populate() argument
399 struct device *dev = &mtd->dev; in mtd_debugfs_populate()
406 mtd->dbg.dfs_dir = root; in mtd_debugfs_populate()
408 if (mtd->dbg.partid) in mtd_debugfs_populate()
409 debugfs_create_file("partid", 0400, root, mtd, in mtd_debugfs_populate()
412 if (mtd->dbg.partname) in mtd_debugfs_populate()
413 debugfs_create_file("partname", 0400, root, mtd, in mtd_debugfs_populate()
418 unsigned mtd_mmap_capabilities(struct mtd_info *mtd) in mtd_mmap_capabilities() argument
420 switch (mtd->type) { in mtd_mmap_capabilities()
437 struct mtd_info *mtd; in mtd_reboot_notifier() local
439 mtd = container_of(n, struct mtd_info, reboot_notifier); in mtd_reboot_notifier()
440 mtd->_reboot(mtd); in mtd_reboot_notifier()
447 * @mtd: pointer to new MTD device info structure
462 * From the pairing info the MTD user can find all the wunits paired with
465 * for (i = 0; i < mtd_pairing_groups(mtd); i++) {
467 * mtd_pairing_info_to_wunit(mtd, &info);
471 int mtd_wunit_to_pairing_info(struct mtd_info *mtd, int wunit, in mtd_wunit_to_pairing_info() argument
474 struct mtd_info *master = mtd_get_master(mtd); in mtd_wunit_to_pairing_info()
492 * @mtd: pointer to new MTD device info structure
507 * npairs = mtd_wunit_per_eb(mtd) / mtd_pairing_groups(mtd);
509 * wunit = mtd_pairing_info_to_wunit(mtd, &info);
510 * mtd_write(mtd, mtd_wunit_to_offset(mtd, blkoffs, wunit),
511 * mtd->writesize, &retlen, buf + (i * mtd->writesize));
514 int mtd_pairing_info_to_wunit(struct mtd_info *mtd, in mtd_pairing_info_to_wunit() argument
517 struct mtd_info *master = mtd_get_master(mtd); in mtd_pairing_info_to_wunit()
526 return mtd->pairing->get_wunit(master, info); in mtd_pairing_info_to_wunit()
534 * @mtd: pointer to new MTD device info structure
542 int mtd_pairing_groups(struct mtd_info *mtd) in mtd_pairing_groups() argument
544 struct mtd_info *master = mtd_get_master(mtd); in mtd_pairing_groups()
556 struct mtd_info *mtd = priv; in mtd_nvmem_reg_read() local
560 err = mtd_read(mtd, offset, bytes, &retlen, val); in mtd_nvmem_reg_read()
567 static int mtd_nvmem_add(struct mtd_info *mtd) in mtd_nvmem_add() argument
572 config.dev = &mtd->dev; in mtd_nvmem_add()
573 config.name = dev_name(&mtd->dev); in mtd_nvmem_add()
576 config.size = mtd->size; in mtd_nvmem_add()
582 config.priv = mtd; in mtd_nvmem_add()
584 mtd->nvmem = nvmem_register(&config); in mtd_nvmem_add()
585 if (IS_ERR(mtd->nvmem)) { in mtd_nvmem_add()
587 if (PTR_ERR(mtd->nvmem) == -EOPNOTSUPP) { in mtd_nvmem_add()
588 mtd->nvmem = NULL; in mtd_nvmem_add()
590 dev_err(&mtd->dev, "Failed to register NVMEM device\n"); in mtd_nvmem_add()
591 return PTR_ERR(mtd->nvmem); in mtd_nvmem_add()
599 * add_mtd_device - register an MTD device
600 * @mtd: pointer to new MTD device info structure
602 * Add a device to the list of MTD devices present in the system, and
603 * notify each currently active MTD 'user' of its arrival. Returns
607 int add_mtd_device(struct mtd_info *mtd) in add_mtd_device() argument
609 struct mtd_info *master = mtd_get_master(mtd); in add_mtd_device()
615 * mtd_device_parse_register() multiple times on the same master MTD, in add_mtd_device()
618 if (WARN_ONCE(mtd->dev.type, "MTD already registered\n")) in add_mtd_device()
621 BUG_ON(mtd->writesize == 0); in add_mtd_device()
624 * MTD drivers should implement ->_{write,read}() or in add_mtd_device()
627 if (WARN_ON((mtd->_write && mtd->_write_oob) || in add_mtd_device()
628 (mtd->_read && mtd->_read_oob))) in add_mtd_device()
631 if (WARN_ON((!mtd->erasesize || !master->_erase) && in add_mtd_device()
632 !(mtd->flags & MTD_NO_ERASE))) in add_mtd_device()
643 if (mtd->flags & MTD_SLC_ON_MLC_EMULATION && in add_mtd_device()
644 (!mtd_is_partition(mtd) || master->type != MTD_MLCNANDFLASH || in add_mtd_device()
650 i = idr_alloc(&mtd_idr, mtd, 0, 0, GFP_KERNEL); in add_mtd_device()
656 mtd->index = i; in add_mtd_device()
657 mtd->usecount = 0; in add_mtd_device()
660 if (mtd->bitflip_threshold == 0) in add_mtd_device()
661 mtd->bitflip_threshold = mtd->ecc_strength; in add_mtd_device()
663 if (mtd->flags & MTD_SLC_ON_MLC_EMULATION) { in add_mtd_device()
666 mtd->erasesize /= ngroups; in add_mtd_device()
667 mtd->size = (u64)mtd_div_by_eb(mtd->size, master) * in add_mtd_device()
668 mtd->erasesize; in add_mtd_device()
671 if (is_power_of_2(mtd->erasesize)) in add_mtd_device()
672 mtd->erasesize_shift = ffs(mtd->erasesize) - 1; in add_mtd_device()
674 mtd->erasesize_shift = 0; in add_mtd_device()
676 if (is_power_of_2(mtd->writesize)) in add_mtd_device()
677 mtd->writesize_shift = ffs(mtd->writesize) - 1; in add_mtd_device()
679 mtd->writesize_shift = 0; in add_mtd_device()
681 mtd->erasesize_mask = (1 << mtd->erasesize_shift) - 1; in add_mtd_device()
682 mtd->writesize_mask = (1 << mtd->writesize_shift) - 1; in add_mtd_device()
685 if ((mtd->flags & MTD_WRITEABLE) && (mtd->flags & MTD_POWERUP_LOCK)) { in add_mtd_device()
686 error = mtd_unlock(mtd, 0, mtd->size); in add_mtd_device()
690 mtd->name); in add_mtd_device()
698 mtd->dev.type = &mtd_devtype; in add_mtd_device()
699 mtd->dev.class = &mtd_class; in add_mtd_device()
700 mtd->dev.devt = MTD_DEVT(i); in add_mtd_device()
701 dev_set_name(&mtd->dev, "mtd%d", i); in add_mtd_device()
702 dev_set_drvdata(&mtd->dev, mtd); in add_mtd_device()
703 of_node_get(mtd_get_of_node(mtd)); in add_mtd_device()
704 error = device_register(&mtd->dev); in add_mtd_device()
706 put_device(&mtd->dev); in add_mtd_device()
711 error = mtd_nvmem_add(mtd); in add_mtd_device()
715 mtd_debugfs_populate(mtd); in add_mtd_device()
717 device_create(&mtd_class, mtd->dev.parent, MTD_DEVT(i) + 1, NULL, in add_mtd_device()
718 "mtd%dro", i); in add_mtd_device()
720 pr_debug("mtd: Giving out device %d to %s\n", i, mtd->name); in add_mtd_device()
724 not->add(mtd); in add_mtd_device()
735 device_unregister(&mtd->dev); in add_mtd_device()
737 of_node_put(mtd_get_of_node(mtd)); in add_mtd_device()
745 * del_mtd_device - unregister an MTD device
746 * @mtd: pointer to MTD device info structure
748 * Remove a device from the list of MTD devices present in the system,
749 * and notify each currently active MTD 'user' of its departure.
754 int del_mtd_device(struct mtd_info *mtd) in del_mtd_device() argument
761 if (idr_find(&mtd_idr, mtd->index) != mtd) { in del_mtd_device()
769 not->remove(mtd); in del_mtd_device()
771 if (mtd->usecount) { in del_mtd_device()
772 printk(KERN_NOTICE "Removing MTD device #%d (%s) with use count %d\n", in del_mtd_device()
773 mtd->index, mtd->name, mtd->usecount); in del_mtd_device()
776 debugfs_remove_recursive(mtd->dbg.dfs_dir); in del_mtd_device()
779 if (mtd->nvmem) in del_mtd_device()
780 nvmem_unregister(mtd->nvmem); in del_mtd_device()
782 device_unregister(&mtd->dev); in del_mtd_device()
784 idr_remove(&mtd_idr, mtd->index); in del_mtd_device()
785 of_node_put(mtd_get_of_node(mtd)); in del_mtd_device()
800 static void mtd_set_dev_defaults(struct mtd_info *mtd) in mtd_set_dev_defaults() argument
802 if (mtd->dev.parent) { in mtd_set_dev_defaults()
803 if (!mtd->owner && mtd->dev.parent->driver) in mtd_set_dev_defaults()
804 mtd->owner = mtd->dev.parent->driver->owner; in mtd_set_dev_defaults()
805 if (!mtd->name) in mtd_set_dev_defaults()
806 mtd->name = dev_name(mtd->dev.parent); in mtd_set_dev_defaults()
808 pr_debug("mtd device won't show a device symlink in sysfs\n"); in mtd_set_dev_defaults()
811 INIT_LIST_HEAD(&mtd->partitions); in mtd_set_dev_defaults()
812 mutex_init(&mtd->master.partitions_lock); in mtd_set_dev_defaults()
816 * mtd_device_parse_register - parse partitions and register an MTD device.
818 * @mtd: the MTD device to register
819 * @types: the list of MTD partition probes to try, see
821 * @parser_data: MTD partition parser-specific data
825 * MTD device is registered if no partition info is found
827 * This function aggregates MTD partitions parsing (done by
828 * 'parse_mtd_partitions()') and MTD device and partitions registering. It
829 * basically follows the most common pattern found in many MTD drivers:
833 * * Then It tries to probe partitions on MTD device @mtd using parsers
838 * * If no partitions were found this function just registers the MTD device
839 * @mtd and exits.
843 int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types, in mtd_device_parse_register() argument
850 mtd_set_dev_defaults(mtd); in mtd_device_parse_register()
853 ret = add_mtd_device(mtd); in mtd_device_parse_register()
859 ret = parse_mtd_partitions(mtd, types, parser_data); in mtd_device_parse_register()
866 ret = add_mtd_partitions(mtd, parts, nr_parts); in mtd_device_parse_register()
867 else if (!device_is_registered(&mtd->dev)) in mtd_device_parse_register()
868 ret = add_mtd_device(mtd); in mtd_device_parse_register()
883 WARN_ONCE(mtd->_reboot && mtd->reboot_notifier.notifier_call, in mtd_device_parse_register()
884 "MTD already registered\n"); in mtd_device_parse_register()
885 if (mtd->_reboot && !mtd->reboot_notifier.notifier_call) { in mtd_device_parse_register()
886 mtd->reboot_notifier.notifier_call = mtd_reboot_notifier; in mtd_device_parse_register()
887 register_reboot_notifier(&mtd->reboot_notifier); in mtd_device_parse_register()
891 if (ret && device_is_registered(&mtd->dev)) in mtd_device_parse_register()
892 del_mtd_device(mtd); in mtd_device_parse_register()
899 * mtd_device_unregister - unregister an existing MTD device.
901 * @master: the MTD device to unregister. This will unregister both the master
923 * register_mtd_user - register a 'user' of MTD devices.
927 * or removal of MTD devices. Causes the 'add' callback to be immediately
928 * invoked for each MTD device currently present in the system.
932 struct mtd_info *mtd; in register_mtd_user() local
940 mtd_for_each_device(mtd) in register_mtd_user()
941 new->add(mtd); in register_mtd_user()
948 * unregister_mtd_user - unregister a 'user' of MTD devices.
952 * notified upon addition or removal of MTD devices. Causes the
953 * 'remove' callback to be immediately invoked for each MTD device
958 struct mtd_info *mtd; in unregister_mtd_user() local
964 mtd_for_each_device(mtd) in unregister_mtd_user()
965 old->remove(mtd); in unregister_mtd_user()
974 * get_mtd_device - obtain a validated handle for an MTD device
975 * @mtd: last known address of the required MTD device
976 * @num: internal device number of the required MTD device
984 struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num) in get_mtd_device() argument
993 if (other == mtd) { in get_mtd_device()
994 ret = mtd; in get_mtd_device()
1000 if (mtd && mtd != ret) in get_mtd_device()
1019 int __get_mtd_device(struct mtd_info *mtd) in __get_mtd_device() argument
1021 struct mtd_info *master = mtd_get_master(mtd); in __get_mtd_device()
1028 err = master->_get_device(mtd); in __get_mtd_device()
1038 while (mtd->parent) { in __get_mtd_device()
1039 mtd->usecount++; in __get_mtd_device()
1040 mtd = mtd->parent; in __get_mtd_device()
1048 * get_mtd_device_nm - obtain a validated handle for an MTD device by
1050 * @name: MTD device name to open
1052 * This function returns MTD device description structure in case of
1058 struct mtd_info *mtd = NULL, *other; in get_mtd_device_nm() local
1064 mtd = other; in get_mtd_device_nm()
1069 if (!mtd) in get_mtd_device_nm()
1072 err = __get_mtd_device(mtd); in get_mtd_device_nm()
1077 return mtd; in get_mtd_device_nm()
1085 void put_mtd_device(struct mtd_info *mtd) in put_mtd_device() argument
1088 __put_mtd_device(mtd); in put_mtd_device()
1094 void __put_mtd_device(struct mtd_info *mtd) in __put_mtd_device() argument
1096 struct mtd_info *master = mtd_get_master(mtd); in __put_mtd_device()
1098 while (mtd->parent) { in __put_mtd_device()
1099 --mtd->usecount; in __put_mtd_device()
1100 BUG_ON(mtd->usecount < 0); in __put_mtd_device()
1101 mtd = mtd->parent; in __put_mtd_device()
1118 int mtd_erase(struct mtd_info *mtd, struct erase_info *instr) in mtd_erase() argument
1120 struct mtd_info *master = mtd_get_master(mtd); in mtd_erase()
1121 u64 mst_ofs = mtd_get_master_ofs(mtd, 0); in mtd_erase()
1128 if (!mtd->erasesize || !master->_erase) in mtd_erase()
1131 if (instr->addr >= mtd->size || instr->len > mtd->size - instr->addr) in mtd_erase()
1133 if (!(mtd->flags & MTD_WRITEABLE)) in mtd_erase()
1141 if (mtd->flags & MTD_SLC_ON_MLC_EMULATION) { in mtd_erase()
1142 adjinstr.addr = (loff_t)mtd_div_by_eb(instr->addr, mtd) * in mtd_erase()
1144 adjinstr.len = ((u64)mtd_div_by_eb(instr->addr + instr->len, mtd) * in mtd_erase()
1155 if (mtd->flags & MTD_SLC_ON_MLC_EMULATION) { in mtd_erase()
1158 instr->fail_addr *= mtd->erasesize; in mtd_erase()
1169 int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, in mtd_point() argument
1172 struct mtd_info *master = mtd_get_master(mtd); in mtd_point()
1180 if (from < 0 || from >= mtd->size || len > mtd->size - from) in mtd_point()
1185 from = mtd_get_master_ofs(mtd, from); in mtd_point()
1191 int mtd_unpoint(struct mtd_info *mtd, loff_t from, size_t len) in mtd_unpoint() argument
1193 struct mtd_info *master = mtd_get_master(mtd); in mtd_unpoint()
1197 if (from < 0 || from >= mtd->size || len > mtd->size - from) in mtd_unpoint()
1201 return master->_unpoint(master, mtd_get_master_ofs(mtd, from), len); in mtd_unpoint()
1210 unsigned long mtd_get_unmapped_area(struct mtd_info *mtd, unsigned long len, in mtd_get_unmapped_area() argument
1217 ret = mtd_point(mtd, offset, len, &retlen, &virt, NULL); in mtd_get_unmapped_area()
1221 mtd_unpoint(mtd, offset, retlen); in mtd_get_unmapped_area()
1228 static void mtd_update_ecc_stats(struct mtd_info *mtd, struct mtd_info *master, in mtd_update_ecc_stats() argument
1233 if (master == mtd) in mtd_update_ecc_stats()
1240 while (mtd->parent) { in mtd_update_ecc_stats()
1241 mtd->ecc_stats.failed += diff.failed; in mtd_update_ecc_stats()
1242 mtd->ecc_stats.corrected += diff.corrected; in mtd_update_ecc_stats()
1243 mtd = mtd->parent; in mtd_update_ecc_stats()
1247 int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, in mtd_read() argument
1256 ret = mtd_read_oob(mtd, from, &ops); in mtd_read()
1263 int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, in mtd_write() argument
1272 ret = mtd_write_oob(mtd, to, &ops); in mtd_write()
1286 int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, in mtd_panic_write() argument
1289 struct mtd_info *master = mtd_get_master(mtd); in mtd_panic_write()
1294 if (to < 0 || to >= mtd->size || len > mtd->size - to) in mtd_panic_write()
1296 if (!(mtd->flags & MTD_WRITEABLE)) in mtd_panic_write()
1303 return master->_panic_write(master, mtd_get_master_ofs(mtd, to), len, in mtd_panic_write()
1308 static int mtd_check_oob_ops(struct mtd_info *mtd, loff_t offs, in mtd_check_oob_ops() argument
1322 if (offs < 0 || offs + ops->len > mtd->size) in mtd_check_oob_ops()
1328 if (ops->ooboffs >= mtd_oobavail(mtd, ops)) in mtd_check_oob_ops()
1331 maxooblen = ((size_t)(mtd_div_by_ws(mtd->size, mtd) - in mtd_check_oob_ops()
1332 mtd_div_by_ws(offs, mtd)) * in mtd_check_oob_ops()
1333 mtd_oobavail(mtd, ops)) - ops->ooboffs; in mtd_check_oob_ops()
1341 static int mtd_read_oob_std(struct mtd_info *mtd, loff_t from, in mtd_read_oob_std() argument
1344 struct mtd_info *master = mtd_get_master(mtd); in mtd_read_oob_std()
1347 from = mtd_get_master_ofs(mtd, from); in mtd_read_oob_std()
1357 static int mtd_write_oob_std(struct mtd_info *mtd, loff_t to, in mtd_write_oob_std() argument
1360 struct mtd_info *master = mtd_get_master(mtd); in mtd_write_oob_std()
1363 to = mtd_get_master_ofs(mtd, to); in mtd_write_oob_std()
1373 static int mtd_io_emulated_slc(struct mtd_info *mtd, loff_t start, bool read, in mtd_io_emulated_slc() argument
1376 struct mtd_info *master = mtd_get_master(mtd); in mtd_io_emulated_slc()
1386 ebofs = mtd_mod_by_eb(start, mtd); in mtd_io_emulated_slc()
1387 base = (loff_t)mtd_div_by_eb(start, mtd) * master->erasesize; in mtd_io_emulated_slc()
1389 info.pair = mtd_div_by_ws(ebofs, mtd); in mtd_io_emulated_slc()
1390 pageofs = mtd_mod_by_ws(ebofs, mtd); in mtd_io_emulated_slc()
1391 oobavail = mtd_oobavail(mtd, ops); in mtd_io_emulated_slc()
1402 pos = mtd_wunit_to_offset(mtd, base, wunit); in mtd_io_emulated_slc()
1405 if (adjops.len > mtd->writesize - pageofs) in mtd_io_emulated_slc()
1406 adjops.len = mtd->writesize - pageofs; in mtd_io_emulated_slc()
1413 ret = mtd_read_oob_std(mtd, pos + pageofs, &adjops); in mtd_io_emulated_slc()
1417 ret = mtd_write_oob_std(mtd, pos + pageofs, &adjops); in mtd_io_emulated_slc()
1436 int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops) in mtd_read_oob() argument
1438 struct mtd_info *master = mtd_get_master(mtd); in mtd_read_oob()
1444 ret_code = mtd_check_oob_ops(mtd, from, ops); in mtd_read_oob()
1450 /* Check the validity of a potential fallback on mtd->_read */ in mtd_read_oob()
1454 if (mtd->flags & MTD_SLC_ON_MLC_EMULATION) in mtd_read_oob()
1455 ret_code = mtd_io_emulated_slc(mtd, from, true, ops); in mtd_read_oob()
1457 ret_code = mtd_read_oob_std(mtd, from, ops); in mtd_read_oob()
1459 mtd_update_ecc_stats(mtd, master, &old_stats); in mtd_read_oob()
1462 * In cases where ops->datbuf != NULL, mtd->_read_oob() has semantics in mtd_read_oob()
1463 * similar to mtd->_read(), returning a non-negative integer in mtd_read_oob()
1464 * representing max bitflips. In other cases, mtd->_read_oob() may in mtd_read_oob()
1469 if (mtd->ecc_strength == 0) in mtd_read_oob()
1471 return ret_code >= mtd->bitflip_threshold ? -EUCLEAN : 0; in mtd_read_oob()
1475 int mtd_write_oob(struct mtd_info *mtd, loff_t to, in mtd_write_oob() argument
1478 struct mtd_info *master = mtd_get_master(mtd); in mtd_write_oob()
1483 if (!(mtd->flags & MTD_WRITEABLE)) in mtd_write_oob()
1486 ret = mtd_check_oob_ops(mtd, to, ops); in mtd_write_oob()
1492 /* Check the validity of a potential fallback on mtd->_write */ in mtd_write_oob()
1496 if (mtd->flags & MTD_SLC_ON_MLC_EMULATION) in mtd_write_oob()
1497 return mtd_io_emulated_slc(mtd, to, false, ops); in mtd_write_oob()
1499 return mtd_write_oob_std(mtd, to, ops); in mtd_write_oob()
1505 * @mtd: MTD device structure
1515 * mtd_ooblayout_ecc(mtd, section++, oobecc) until it returns -ERANGE.
1519 int mtd_ooblayout_ecc(struct mtd_info *mtd, int section, in mtd_ooblayout_ecc() argument
1522 struct mtd_info *master = mtd_get_master(mtd); in mtd_ooblayout_ecc()
1539 * @mtd: MTD device structure
1549 * mtd_ooblayout_free(mtd, section++, oobfree) until it returns -ERANGE.
1553 int mtd_ooblayout_free(struct mtd_info *mtd, int section, in mtd_ooblayout_free() argument
1556 struct mtd_info *master = mtd_get_master(mtd); in mtd_ooblayout_free()
1572 * @mtd: mtd info structure
1583 * mtd_ooblayout_find_region(mtd, 3, §ion, &oobregion, mtd_ooblayout_ecc);
1587 static int mtd_ooblayout_find_region(struct mtd_info *mtd, int byte, in mtd_ooblayout_find_region() argument
1598 ret = iter(mtd, section, oobregion); in mtd_ooblayout_find_region()
1623 * @mtd: mtd info structure
1633 int mtd_ooblayout_find_eccregion(struct mtd_info *mtd, int eccbyte, in mtd_ooblayout_find_eccregion() argument
1637 return mtd_ooblayout_find_region(mtd, eccbyte, section, oobregion, in mtd_ooblayout_find_eccregion()
1644 * @mtd: mtd info structure
1656 static int mtd_ooblayout_get_bytes(struct mtd_info *mtd, u8 *buf, in mtd_ooblayout_get_bytes() argument
1665 ret = mtd_ooblayout_find_region(mtd, start, §ion, in mtd_ooblayout_get_bytes()
1679 ret = iter(mtd, ++section, &oobregion); in mtd_ooblayout_get_bytes()
1687 * @mtd: mtd info structure
1699 static int mtd_ooblayout_set_bytes(struct mtd_info *mtd, const u8 *buf, in mtd_ooblayout_set_bytes() argument
1708 ret = mtd_ooblayout_find_region(mtd, start, §ion, in mtd_ooblayout_set_bytes()
1722 ret = iter(mtd, ++section, &oobregion); in mtd_ooblayout_set_bytes()
1730 * @mtd: mtd info structure
1737 static int mtd_ooblayout_count_bytes(struct mtd_info *mtd, in mtd_ooblayout_count_bytes() argument
1746 ret = iter(mtd, section++, &oobregion); in mtd_ooblayout_count_bytes()
1761 * @mtd: mtd info structure
1771 int mtd_ooblayout_get_eccbytes(struct mtd_info *mtd, u8 *eccbuf, in mtd_ooblayout_get_eccbytes() argument
1774 return mtd_ooblayout_get_bytes(mtd, eccbuf, oobbuf, start, nbytes, in mtd_ooblayout_get_eccbytes()
1781 * @mtd: mtd info structure
1791 int mtd_ooblayout_set_eccbytes(struct mtd_info *mtd, const u8 *eccbuf, in mtd_ooblayout_set_eccbytes() argument
1794 return mtd_ooblayout_set_bytes(mtd, eccbuf, oobbuf, start, nbytes, in mtd_ooblayout_set_eccbytes()
1801 * @mtd: mtd info structure
1811 int mtd_ooblayout_get_databytes(struct mtd_info *mtd, u8 *databuf, in mtd_ooblayout_get_databytes() argument
1814 return mtd_ooblayout_get_bytes(mtd, databuf, oobbuf, start, nbytes, in mtd_ooblayout_get_databytes()
1821 * @mtd: mtd info structure
1831 int mtd_ooblayout_set_databytes(struct mtd_info *mtd, const u8 *databuf, in mtd_ooblayout_set_databytes() argument
1834 return mtd_ooblayout_set_bytes(mtd, databuf, oobbuf, start, nbytes, in mtd_ooblayout_set_databytes()
1841 * @mtd: mtd info structure
1847 int mtd_ooblayout_count_freebytes(struct mtd_info *mtd) in mtd_ooblayout_count_freebytes() argument
1849 return mtd_ooblayout_count_bytes(mtd, mtd_ooblayout_free); in mtd_ooblayout_count_freebytes()
1855 * @mtd: mtd info structure
1861 int mtd_ooblayout_count_eccbytes(struct mtd_info *mtd) in mtd_ooblayout_count_eccbytes() argument
1863 return mtd_ooblayout_count_bytes(mtd, mtd_ooblayout_ecc); in mtd_ooblayout_count_eccbytes()
1872 int mtd_get_fact_prot_info(struct mtd_info *mtd, size_t len, size_t *retlen, in mtd_get_fact_prot_info() argument
1875 struct mtd_info *master = mtd_get_master(mtd); in mtd_get_fact_prot_info()
1885 int mtd_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, size_t len, in mtd_read_fact_prot_reg() argument
1888 struct mtd_info *master = mtd_get_master(mtd); in mtd_read_fact_prot_reg()
1899 int mtd_get_user_prot_info(struct mtd_info *mtd, size_t len, size_t *retlen, in mtd_get_user_prot_info() argument
1902 struct mtd_info *master = mtd_get_master(mtd); in mtd_get_user_prot_info()
1912 int mtd_read_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len, in mtd_read_user_prot_reg() argument
1915 struct mtd_info *master = mtd_get_master(mtd); in mtd_read_user_prot_reg()
1926 int mtd_write_user_prot_reg(struct mtd_info *mtd, loff_t to, size_t len, in mtd_write_user_prot_reg() argument
1929 struct mtd_info *master = mtd_get_master(mtd); in mtd_write_user_prot_reg()
1949 int mtd_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len) in mtd_lock_user_prot_reg() argument
1951 struct mtd_info *master = mtd_get_master(mtd); in mtd_lock_user_prot_reg()
1962 int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) in mtd_lock() argument
1964 struct mtd_info *master = mtd_get_master(mtd); in mtd_lock()
1968 if (ofs < 0 || ofs >= mtd->size || len > mtd->size - ofs) in mtd_lock()
1973 if (mtd->flags & MTD_SLC_ON_MLC_EMULATION) { in mtd_lock()
1974 ofs = (loff_t)mtd_div_by_eb(ofs, mtd) * master->erasesize; in mtd_lock()
1975 len = (u64)mtd_div_by_eb(len, mtd) * master->erasesize; in mtd_lock()
1978 return master->_lock(master, mtd_get_master_ofs(mtd, ofs), len); in mtd_lock()
1982 int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) in mtd_unlock() argument
1984 struct mtd_info *master = mtd_get_master(mtd); in mtd_unlock()
1988 if (ofs < 0 || ofs >= mtd->size || len > mtd->size - ofs) in mtd_unlock()
1993 if (mtd->flags & MTD_SLC_ON_MLC_EMULATION) { in mtd_unlock()
1994 ofs = (loff_t)mtd_div_by_eb(ofs, mtd) * master->erasesize; in mtd_unlock()
1995 len = (u64)mtd_div_by_eb(len, mtd) * master->erasesize; in mtd_unlock()
1998 return master->_unlock(master, mtd_get_master_ofs(mtd, ofs), len); in mtd_unlock()
2002 int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) in mtd_is_locked() argument
2004 struct mtd_info *master = mtd_get_master(mtd); in mtd_is_locked()
2008 if (ofs < 0 || ofs >= mtd->size || len > mtd->size - ofs) in mtd_is_locked()
2013 if (mtd->flags & MTD_SLC_ON_MLC_EMULATION) { in mtd_is_locked()
2014 ofs = (loff_t)mtd_div_by_eb(ofs, mtd) * master->erasesize; in mtd_is_locked()
2015 len = (u64)mtd_div_by_eb(len, mtd) * master->erasesize; in mtd_is_locked()
2018 return master->_is_locked(master, mtd_get_master_ofs(mtd, ofs), len); in mtd_is_locked()
2022 int mtd_block_isreserved(struct mtd_info *mtd, loff_t ofs) in mtd_block_isreserved() argument
2024 struct mtd_info *master = mtd_get_master(mtd); in mtd_block_isreserved()
2026 if (ofs < 0 || ofs >= mtd->size) in mtd_block_isreserved()
2031 if (mtd->flags & MTD_SLC_ON_MLC_EMULATION) in mtd_block_isreserved()
2032 ofs = (loff_t)mtd_div_by_eb(ofs, mtd) * master->erasesize; in mtd_block_isreserved()
2034 return master->_block_isreserved(master, mtd_get_master_ofs(mtd, ofs)); in mtd_block_isreserved()
2038 int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs) in mtd_block_isbad() argument
2040 struct mtd_info *master = mtd_get_master(mtd); in mtd_block_isbad()
2042 if (ofs < 0 || ofs >= mtd->size) in mtd_block_isbad()
2047 if (mtd->flags & MTD_SLC_ON_MLC_EMULATION) in mtd_block_isbad()
2048 ofs = (loff_t)mtd_div_by_eb(ofs, mtd) * master->erasesize; in mtd_block_isbad()
2050 return master->_block_isbad(master, mtd_get_master_ofs(mtd, ofs)); in mtd_block_isbad()
2054 int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs) in mtd_block_markbad() argument
2056 struct mtd_info *master = mtd_get_master(mtd); in mtd_block_markbad()
2061 if (ofs < 0 || ofs >= mtd->size) in mtd_block_markbad()
2063 if (!(mtd->flags & MTD_WRITEABLE)) in mtd_block_markbad()
2066 if (mtd->flags & MTD_SLC_ON_MLC_EMULATION) in mtd_block_markbad()
2067 ofs = (loff_t)mtd_div_by_eb(ofs, mtd) * master->erasesize; in mtd_block_markbad()
2069 ret = master->_block_markbad(master, mtd_get_master_ofs(mtd, ofs)); in mtd_block_markbad()
2073 while (mtd->parent) { in mtd_block_markbad()
2074 mtd->ecc_stats.badblocks++; in mtd_block_markbad()
2075 mtd = mtd->parent; in mtd_block_markbad()
2084 * @mtd: mtd device description object pointer
2087 * @to: the MTD device offset to write to
2088 * @retlen: on exit contains the count of bytes written to the MTD device.
2093 static int default_mtd_writev(struct mtd_info *mtd, const struct kvec *vecs, in default_mtd_writev() argument
2103 ret = mtd_write(mtd, to, vecs[i].iov_len, &thislen, in default_mtd_writev()
2115 * mtd_writev - the vector-based MTD write method
2116 * @mtd: mtd device description object pointer
2119 * @to: the MTD device offset to write to
2120 * @retlen: on exit contains the count of bytes written to the MTD device.
2125 int mtd_writev(struct mtd_info *mtd, const struct kvec *vecs, in mtd_writev() argument
2128 struct mtd_info *master = mtd_get_master(mtd); in mtd_writev()
2131 if (!(mtd->flags & MTD_WRITEABLE)) in mtd_writev()
2135 return default_mtd_writev(mtd, vecs, count, to, retlen); in mtd_writev()
2138 mtd_get_master_ofs(mtd, to), retlen); in mtd_writev()
2144 * @mtd: mtd device description object pointer
2157 * the MTD device's min. I/O unit, i.e. the "mtd->writesize" value.
2166 void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size) in mtd_kmalloc_up_to() argument
2169 size_t min_alloc = max_t(size_t, mtd->writesize, PAGE_SIZE); in mtd_kmalloc_up_to()
2180 *size = ALIGN(*size, mtd->writesize); in mtd_kmalloc_up_to()
2194 /* Support for /proc/mtd */
2198 struct mtd_info *mtd; in mtd_proc_show() local
2202 mtd_for_each_device(mtd) { in mtd_proc_show()
2203 seq_printf(m, "mtd%d: %8.8llx %8.8x \"%s\"\n", in mtd_proc_show()
2204 mtd->index, (unsigned long long)mtd->size, in mtd_proc_show()
2205 mtd->erasesize, mtd->name); in mtd_proc_show()
2247 mtd_bdi = mtd_bdi_init("mtd"); in init_mtd()
2253 proc_mtd = proc_create_single("mtd", 0, NULL, mtd_proc_show); in init_mtd()
2259 dfs_dir_mtd = debugfs_create_dir("mtd", NULL); in init_mtd()
2265 remove_proc_entry("mtd", NULL); in init_mtd()
2270 pr_err("Error registering mtd class or bdi: %d\n", ret); in init_mtd()
2279 remove_proc_entry("mtd", NULL); in cleanup_mtd()
2290 MODULE_DESCRIPTION("Core MTD registration and access routines");