summaryrefslogtreecommitdiffstats
path: root/target/linux/sunxi/patches-4.1/113-mtd-nand-add-pst.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/sunxi/patches-4.1/113-mtd-nand-add-pst.patch')
-rw-r--r--target/linux/sunxi/patches-4.1/113-mtd-nand-add-pst.patch261
1 files changed, 0 insertions, 261 deletions
diff --git a/target/linux/sunxi/patches-4.1/113-mtd-nand-add-pst.patch b/target/linux/sunxi/patches-4.1/113-mtd-nand-add-pst.patch
deleted file mode 100644
index 45b9679d66..0000000000
--- a/target/linux/sunxi/patches-4.1/113-mtd-nand-add-pst.patch
+++ /dev/null
@@ -1,261 +0,0 @@
-From bec69bb8e85151729014d859106dcc3fe652b1d4 Mon Sep 17 00:00:00 2001
-From: Boris BREZILLON <boris.brezillon@free-electrons.com>
-Date: Mon, 28 Jul 2014 14:45:40 +0200
-Subject: [PATCH] mtd: nand: Add page status table (pst)
-
-Page status table is an byte array storing pages status.
-It defines 3 status:
- - unknown: the page has not been read yet and we do not know its current
- state
- - empty: the page contains only FFs
- - filled: the page has been filled with data
-
-Care must be taken: an empty page does not mean it can be written, because
-it might have already been written with only FFs.
-
-These page status are useful to check wether the controller should try to
-correct errors (using ECC) or a derandomize data (using a randomizer
-block).
-
-Signed-off-by: Boris BREZILLON <boris.brezillon@free-electrons.com>
-Signed-off-by: Hans de Goede <hdegoede@redhat.com>
----
- drivers/mtd/nand/nand_base.c | 154 +++++++++++++++++++++++++++++++++++++++++++
- include/linux/mtd/nand.h | 21 ++++++
- 2 files changed, 175 insertions(+)
-
---- a/drivers/mtd/nand/nand_base.c
-+++ b/drivers/mtd/nand/nand_base.c
-@@ -1102,6 +1102,138 @@ out:
- EXPORT_SYMBOL(nand_lock);
-
- /**
-+ * nand_page_is_empty - check wether a NAND page contains only FFs
-+ * @mtd: mtd info
-+ * @data: data buffer
-+ * @oob: oob buffer
-+ *
-+ * Reads the data stored in the databuf buffer and check if it contains only
-+ * FFs.
-+ *
-+ * Return true if it does else return false.
-+ */
-+bool nand_page_is_empty(struct mtd_info *mtd, void *data, void *oob)
-+{
-+ u8 *buf;
-+ int length;
-+ u32 pattern = 0xffffffff;
-+ int bitflips = 0;
-+ int cnt;
-+
-+ buf = data;
-+ length = mtd->writesize;
-+ while (length) {
-+ cnt = length < sizeof(pattern) ? length : sizeof(pattern);
-+ if (memcmp(&pattern, buf, cnt)) {
-+ int i;
-+ for (i = 0; i < cnt * BITS_PER_BYTE; i++) {
-+ if (!(buf[i / BITS_PER_BYTE] &
-+ (1 << (i % BITS_PER_BYTE)))) {
-+ bitflips++;
-+ if (bitflips > mtd->ecc_strength)
-+ return false;
-+ }
-+ }
-+ }
-+
-+ buf += sizeof(pattern);
-+ length -= sizeof(pattern);
-+ }
-+
-+ buf = oob;
-+ length = mtd->oobsize;
-+ while (length) {
-+ cnt = length < sizeof(pattern) ? length : sizeof(pattern);
-+ if (memcmp(&pattern, buf, cnt)) {
-+ int i;
-+ for (i = 0; i < cnt * BITS_PER_BYTE; i++) {
-+ if (!(buf[i / BITS_PER_BYTE] &
-+ (1 << (i % BITS_PER_BYTE)))) {
-+ bitflips++;
-+ if (bitflips > mtd->ecc_strength)
-+ return false;
-+ }
-+ }
-+ }
-+
-+ buf += sizeof(pattern);
-+ length -= sizeof(pattern);
-+ }
-+
-+ return true;
-+}
-+EXPORT_SYMBOL(nand_page_is_empty);
-+
-+/**
-+ * nand_page_get_status - retrieve page status from the page status table (pst)
-+ * @mtd: mtd info
-+ * @page: page you want to get status on
-+ *
-+ * Return the page status.
-+ */
-+int nand_page_get_status(struct mtd_info *mtd, int page)
-+{
-+ struct nand_chip *chip = mtd->priv;
-+ u8 shift = (page % 4) * 2;
-+ uint64_t offset = page / 4;
-+ int ret = NAND_PAGE_STATUS_UNKNOWN;
-+
-+ if (chip->pst)
-+ ret = (chip->pst[offset] >> shift) & 0x3;
-+
-+ return ret;
-+}
-+EXPORT_SYMBOL(nand_page_get_status);
-+
-+/**
-+ * nand_page_set_status - assign page status from in the page status table
-+ * @mtd: mtd info
-+ * @page: page you want to get status on
-+ * @status: new status to assign
-+ */
-+void nand_page_set_status(struct mtd_info *mtd, int page,
-+ enum nand_page_status status)
-+{
-+ struct nand_chip *chip = mtd->priv;
-+ u8 shift;
-+ uint64_t offset;
-+
-+ if (!chip->pst)
-+ return;
-+
-+ shift = (page % 4) * 2;
-+ offset = page / 4;
-+ chip->pst[offset] &= ~(0x3 << shift);
-+ chip->pst[offset] |= (status & 0x3) << shift;
-+}
-+EXPORT_SYMBOL(nand_page_set_status);
-+
-+/**
-+ * nand_pst_create - create a page status table
-+ * @mtd: mtd info
-+ *
-+ * Allocate a page status table and assign it to the mtd device.
-+ *
-+ * Returns 0 in case of success or -ERRNO in case of error.
-+ */
-+int nand_pst_create(struct mtd_info *mtd)
-+{
-+ struct nand_chip *chip = mtd->priv;
-+
-+ if (chip->pst)
-+ return 0;
-+
-+ chip->pst = kzalloc(mtd->size >>
-+ (chip->page_shift + mtd->subpage_sft + 2),
-+ GFP_KERNEL);
-+ if (!chip->pst)
-+ return -ENOMEM;
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL(nand_pst_create);
-+
-+/**
- * nand_read_page_raw - [INTERN] read raw page data without ecc
- * @mtd: mtd info structure
- * @chip: nand chip info structure
-@@ -2539,6 +2671,7 @@ static int nand_do_write_ops(struct mtd_
- uint8_t *wbuf = buf;
- int use_bufpoi;
- int part_pagewr = (column || writelen < (mtd->writesize - 1));
-+ int subpage;
-
- if (part_pagewr)
- use_bufpoi = 1;
-@@ -2574,6 +2707,14 @@ static int nand_do_write_ops(struct mtd_
- if (ret)
- break;
-
-+ for (subpage = column / chip->subpagesize;
-+ subpage < (column + writelen) / chip->subpagesize;
-+ subpage++)
-+ nand_page_set_status(mtd,
-+ (page << mtd->subpage_sft) +
-+ subpage,
-+ NAND_PAGE_FILLED);
-+
- writelen -= bytes;
- if (!writelen)
- break;
-@@ -2979,6 +3120,7 @@ int nand_erase_nand(struct mtd_info *mtd
- int page, status, pages_per_block, ret, chipnr;
- struct nand_chip *chip = mtd->priv;
- loff_t len;
-+ int i;
-
- pr_debug("%s: start = 0x%012llx, len = %llu\n",
- __func__, (unsigned long long)instr->addr,
-@@ -3051,6 +3193,18 @@ int nand_erase_nand(struct mtd_info *mtd
- goto erase_exit;
- }
-
-+ for (i = 0; i < pages_per_block; i++) {
-+ int subpage;
-+ for (subpage = 0;
-+ subpage < 1 << mtd->subpage_sft;
-+ subpage++) {
-+ nand_page_set_status(mtd,
-+ ((page + i) << mtd->subpage_sft) +
-+ subpage,
-+ NAND_PAGE_EMPTY);
-+ }
-+ }
-+
- /* Increment page address and decrement length */
- len -= (1ULL << chip->phys_erase_shift);
- page += pages_per_block;
---- a/include/linux/mtd/nand.h
-+++ b/include/linux/mtd/nand.h
-@@ -521,6 +521,24 @@ struct nand_ecc_ctrl {
- int page);
- };
-
-+/*
-+ * Constants for page status
-+ */
-+enum nand_page_status {
-+ NAND_PAGE_STATUS_UNKNOWN,
-+ NAND_PAGE_EMPTY,
-+ NAND_PAGE_FILLED,
-+};
-+
-+bool nand_page_is_empty(struct mtd_info *mtd, void *data, void *oob);
-+
-+int nand_page_get_status(struct mtd_info *mtd, int page);
-+
-+void nand_page_set_status(struct mtd_info *mtd, int page,
-+ enum nand_page_status status);
-+
-+int nand_pst_create(struct mtd_info *mtd);
-+
- /**
- * struct nand_buffers - buffer structure for read/write
- * @ecccalc: buffer pointer for calculated ECC, size is oobsize.
-@@ -630,6 +648,7 @@ struct nand_buffers {
- * @bbt_md: [REPLACEABLE] bad block table mirror descriptor
- * @badblock_pattern: [REPLACEABLE] bad block scan pattern used for initial
- * bad block scan.
-+ * @pst: [INTERN] page status table
- * @controller: [REPLACEABLE] a pointer to a hardware controller
- * structure which is shared among multiple independent
- * devices.
-@@ -718,6 +737,8 @@ struct nand_chip {
-
- struct nand_bbt_descr *badblock_pattern;
-
-+ uint8_t *pst;
-+
- struct list_head partitions;
- struct mutex part_lock;
-