treewide: remove redundant #include <linux/kconfig.h>
[cascardo/linux.git] / drivers / mtd / mtdcore.c
index e3936b8..d46e4ad 100644 (file)
@@ -39,7 +39,6 @@
 #include <linux/gfp.h>
 #include <linux/slab.h>
 #include <linux/reboot.h>
-#include <linux/kconfig.h>
 #include <linux/leds.h>
 
 #include <linux/mtd/mtd.h>
@@ -375,6 +374,110 @@ static int mtd_reboot_notifier(struct notifier_block *n, unsigned long state,
        return NOTIFY_DONE;
 }
 
+/**
+ * mtd_wunit_to_pairing_info - get pairing information of a wunit
+ * @mtd: pointer to new MTD device info structure
+ * @wunit: write unit we are interested in
+ * @info: returned pairing information
+ *
+ * Retrieve pairing information associated to the wunit.
+ * This is mainly useful when dealing with MLC/TLC NANDs where pages can be
+ * paired together, and where programming a page may influence the page it is
+ * paired with.
+ * The notion of page is replaced by the term wunit (write-unit) to stay
+ * consistent with the ->writesize field.
+ *
+ * The @wunit argument can be extracted from an absolute offset using
+ * mtd_offset_to_wunit(). @info is filled with the pairing information attached
+ * to @wunit.
+ *
+ * From the pairing info the MTD user can find all the wunits paired with
+ * @wunit using the following loop:
+ *
+ * for (i = 0; i < mtd_pairing_groups(mtd); i++) {
+ *     info.pair = i;
+ *     mtd_pairing_info_to_wunit(mtd, &info);
+ *     ...
+ * }
+ */
+int mtd_wunit_to_pairing_info(struct mtd_info *mtd, int wunit,
+                             struct mtd_pairing_info *info)
+{
+       int npairs = mtd_wunit_per_eb(mtd) / mtd_pairing_groups(mtd);
+
+       if (wunit < 0 || wunit >= npairs)
+               return -EINVAL;
+
+       if (mtd->pairing && mtd->pairing->get_info)
+               return mtd->pairing->get_info(mtd, wunit, info);
+
+       info->group = 0;
+       info->pair = wunit;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(mtd_wunit_to_pairing_info);
+
+/**
+ * mtd_wunit_to_pairing_info - get wunit from pairing information
+ * @mtd: pointer to new MTD device info structure
+ * @info: pairing information struct
+ *
+ * Returns a positive number representing the wunit associated to the info
+ * struct, or a negative error code.
+ *
+ * This is the reverse of mtd_wunit_to_pairing_info(), and can help one to
+ * iterate over all wunits of a given pair (see mtd_wunit_to_pairing_info()
+ * doc).
+ *
+ * It can also be used to only program the first page of each pair (i.e.
+ * page attached to group 0), which allows one to use an MLC NAND in
+ * software-emulated SLC mode:
+ *
+ * info.group = 0;
+ * npairs = mtd_wunit_per_eb(mtd) / mtd_pairing_groups(mtd);
+ * for (info.pair = 0; info.pair < npairs; info.pair++) {
+ *     wunit = mtd_pairing_info_to_wunit(mtd, &info);
+ *     mtd_write(mtd, mtd_wunit_to_offset(mtd, blkoffs, wunit),
+ *               mtd->writesize, &retlen, buf + (i * mtd->writesize));
+ * }
+ */
+int mtd_pairing_info_to_wunit(struct mtd_info *mtd,
+                             const struct mtd_pairing_info *info)
+{
+       int ngroups = mtd_pairing_groups(mtd);
+       int npairs = mtd_wunit_per_eb(mtd) / ngroups;
+
+       if (!info || info->pair < 0 || info->pair >= npairs ||
+           info->group < 0 || info->group >= ngroups)
+               return -EINVAL;
+
+       if (mtd->pairing && mtd->pairing->get_wunit)
+               return mtd->pairing->get_wunit(mtd, info);
+
+       return info->pair;
+}
+EXPORT_SYMBOL_GPL(mtd_pairing_info_to_wunit);
+
+/**
+ * mtd_pairing_groups - get the number of pairing groups
+ * @mtd: pointer to new MTD device info structure
+ *
+ * Returns the number of pairing groups.
+ *
+ * This number is usually equal to the number of bits exposed by a single
+ * cell, and can be used in conjunction with mtd_pairing_info_to_wunit()
+ * to iterate over all pages of a given pair.
+ */
+int mtd_pairing_groups(struct mtd_info *mtd)
+{
+       if (!mtd->pairing || !mtd->pairing->ngroups)
+               return 1;
+
+       return mtd->pairing->ngroups;
+}
+EXPORT_SYMBOL_GPL(mtd_pairing_groups);
+
 /**
  *     add_mtd_device - register an MTD device
  *     @mtd: pointer to new MTD device info structure