3.16.61-rc1 review patch.  If anyone has any objections, please let me know.

------------------

From: Ben Hutchings <b...@decadent.org.uk>

This reverts commit e7e13fa736726e9860a86e5e1ae19ce162e11b71, which
was commit 739c64414f01748a36e7d82c8e0611dea94412bd upstream.  It
doesn't appear to fix a real bug in 3.16, and it results in build
breakage and/or compiler warnings depending on the kernel
configuration.

Signed-off-by: Ben Hutchings <b...@decadent.org.uk>
---
 drivers/mtd/nand/omap2.c | 340 +++++++++++++--------------------------
 1 file changed, 115 insertions(+), 225 deletions(-)

--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1163,174 +1163,130 @@ static u8  bch8_polynomial[] = {0xef, 0x
                                0x97, 0x79, 0xe5, 0x24, 0xb5};
 
 /**
- * _omap_calculate_ecc_bch - Generate ECC bytes for one sector
+ * omap_calculate_ecc_bch - Generate bytes of ECC bytes
  * @mtd:       MTD device structure
  * @dat:       The pointer to data on which ecc is computed
  * @ecc_code:  The ecc_code buffer
- * @i:         The sector number (for a multi sector page)
  *
- * Support calculating of BCH4/8/16 ECC vectors for one sector
- * within a page. Sector number is in @i.
+ * Support calculating of BCH4/8 ecc vectors for the page
  */
-static int _omap_calculate_ecc_bch(struct mtd_info *mtd,
-                                  const u_char *dat, u_char *ecc_calc, int i)
+static int __maybe_unused omap_calculate_ecc_bch(struct mtd_info *mtd,
+                                       const u_char *dat, u_char *ecc_calc)
 {
        struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
                                                   mtd);
        int eccbytes    = info->nand.ecc.bytes;
        struct gpmc_nand_regs   *gpmc_regs = &info->reg;
        u8 *ecc_code;
-       unsigned long bch_val1, bch_val2, bch_val3, bch_val4;
+       unsigned long nsectors, bch_val1, bch_val2, bch_val3, bch_val4;
        u32 val;
-       int j;
-
-       ecc_code = ecc_calc;
-       switch (info->ecc_opt) {
-       case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
-       case OMAP_ECC_BCH8_CODE_HW:
-               bch_val1 = readl(gpmc_regs->gpmc_bch_result0[i]);
-               bch_val2 = readl(gpmc_regs->gpmc_bch_result1[i]);
-               bch_val3 = readl(gpmc_regs->gpmc_bch_result2[i]);
-               bch_val4 = readl(gpmc_regs->gpmc_bch_result3[i]);
-               *ecc_code++ = (bch_val4 & 0xFF);
-               *ecc_code++ = ((bch_val3 >> 24) & 0xFF);
-               *ecc_code++ = ((bch_val3 >> 16) & 0xFF);
-               *ecc_code++ = ((bch_val3 >> 8) & 0xFF);
-               *ecc_code++ = (bch_val3 & 0xFF);
-               *ecc_code++ = ((bch_val2 >> 24) & 0xFF);
-               *ecc_code++ = ((bch_val2 >> 16) & 0xFF);
-               *ecc_code++ = ((bch_val2 >> 8) & 0xFF);
-               *ecc_code++ = (bch_val2 & 0xFF);
-               *ecc_code++ = ((bch_val1 >> 24) & 0xFF);
-               *ecc_code++ = ((bch_val1 >> 16) & 0xFF);
-               *ecc_code++ = ((bch_val1 >> 8) & 0xFF);
-               *ecc_code++ = (bch_val1 & 0xFF);
-               break;
-       case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW:
-       case OMAP_ECC_BCH4_CODE_HW:
-               bch_val1 = readl(gpmc_regs->gpmc_bch_result0[i]);
-               bch_val2 = readl(gpmc_regs->gpmc_bch_result1[i]);
-               *ecc_code++ = ((bch_val2 >> 12) & 0xFF);
-               *ecc_code++ = ((bch_val2 >> 4) & 0xFF);
-               *ecc_code++ = ((bch_val2 & 0xF) << 4) |
-                       ((bch_val1 >> 28) & 0xF);
-               *ecc_code++ = ((bch_val1 >> 20) & 0xFF);
-               *ecc_code++ = ((bch_val1 >> 12) & 0xFF);
-               *ecc_code++ = ((bch_val1 >> 4) & 0xFF);
-               *ecc_code++ = ((bch_val1 & 0xF) << 4);
-               break;
-       case OMAP_ECC_BCH16_CODE_HW:
-               val = readl(gpmc_regs->gpmc_bch_result6[i]);
-               ecc_code[0]  = ((val >>  8) & 0xFF);
-               ecc_code[1]  = ((val >>  0) & 0xFF);
-               val = readl(gpmc_regs->gpmc_bch_result5[i]);
-               ecc_code[2]  = ((val >> 24) & 0xFF);
-               ecc_code[3]  = ((val >> 16) & 0xFF);
-               ecc_code[4]  = ((val >>  8) & 0xFF);
-               ecc_code[5]  = ((val >>  0) & 0xFF);
-               val = readl(gpmc_regs->gpmc_bch_result4[i]);
-               ecc_code[6]  = ((val >> 24) & 0xFF);
-               ecc_code[7]  = ((val >> 16) & 0xFF);
-               ecc_code[8]  = ((val >>  8) & 0xFF);
-               ecc_code[9]  = ((val >>  0) & 0xFF);
-               val = readl(gpmc_regs->gpmc_bch_result3[i]);
-               ecc_code[10] = ((val >> 24) & 0xFF);
-               ecc_code[11] = ((val >> 16) & 0xFF);
-               ecc_code[12] = ((val >>  8) & 0xFF);
-               ecc_code[13] = ((val >>  0) & 0xFF);
-               val = readl(gpmc_regs->gpmc_bch_result2[i]);
-               ecc_code[14] = ((val >> 24) & 0xFF);
-               ecc_code[15] = ((val >> 16) & 0xFF);
-               ecc_code[16] = ((val >>  8) & 0xFF);
-               ecc_code[17] = ((val >>  0) & 0xFF);
-               val = readl(gpmc_regs->gpmc_bch_result1[i]);
-               ecc_code[18] = ((val >> 24) & 0xFF);
-               ecc_code[19] = ((val >> 16) & 0xFF);
-               ecc_code[20] = ((val >>  8) & 0xFF);
-               ecc_code[21] = ((val >>  0) & 0xFF);
-               val = readl(gpmc_regs->gpmc_bch_result0[i]);
-               ecc_code[22] = ((val >> 24) & 0xFF);
-               ecc_code[23] = ((val >> 16) & 0xFF);
-               ecc_code[24] = ((val >>  8) & 0xFF);
-               ecc_code[25] = ((val >>  0) & 0xFF);
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       /* ECC scheme specific syndrome customizations */
-       switch (info->ecc_opt) {
-       case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW:
-               /* Add constant polynomial to remainder, so that
-                * ECC of blank pages results in 0x0 on reading back
-                */
-               for (j = 0; j < eccbytes; j++)
-                       ecc_calc[j] ^= bch4_polynomial[j];
-               break;
-       case OMAP_ECC_BCH4_CODE_HW:
-               /* Set  8th ECC byte as 0x0 for ROM compatibility */
-               ecc_calc[eccbytes - 1] = 0x0;
-               break;
-       case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
-               /* Add constant polynomial to remainder, so that
-                * ECC of blank pages results in 0x0 on reading back
-                */
-               for (j = 0; j < eccbytes; j++)
-                       ecc_calc[j] ^= bch8_polynomial[j];
-               break;
-       case OMAP_ECC_BCH8_CODE_HW:
-               /* Set 14th ECC byte as 0x0 for ROM compatibility */
-               ecc_calc[eccbytes - 1] = 0x0;
-               break;
-       case OMAP_ECC_BCH16_CODE_HW:
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-/**
- * omap_calculate_ecc_bch_sw - ECC generator for sector for SW based correction
- * @mtd:       MTD device structure
- * @dat:       The pointer to data on which ecc is computed
- * @ecc_code:  The ecc_code buffer
- *
- * Support calculating of BCH4/8/16 ECC vectors for one sector. This is used
- * when SW based correction is required as ECC is required for one sector
- * at a time.
- */
-static int omap_calculate_ecc_bch_sw(struct mtd_info *mtd,
-                                    const u_char *dat, u_char *ecc_calc)
-{
-       return _omap_calculate_ecc_bch(mtd, dat, ecc_calc, 0);
-}
-
-/**
- * omap_calculate_ecc_bch_multi - Generate ECC for multiple sectors
- * @mtd:       MTD device structure
- * @dat:       The pointer to data on which ecc is computed
- * @ecc_code:  The ecc_code buffer
- *
- * Support calculating of BCH4/8/16 ecc vectors for the entire page in one go.
- */
-static int omap_calculate_ecc_bch_multi(struct mtd_info *mtd,
-                                       const u_char *dat, u_char *ecc_calc)
-{
-       struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
-                                                  mtd);
-       int eccbytes = info->nand.ecc.bytes;
-       unsigned long nsectors;
-       int i, ret;
+       int i, j;
 
        nsectors = ((readl(info->reg.gpmc_ecc_config) >> 4) & 0x7) + 1;
        for (i = 0; i < nsectors; i++) {
-               ret = _omap_calculate_ecc_bch(mtd, dat, ecc_calc, i);
-               if (ret)
-                       return ret;
+               ecc_code = ecc_calc;
+               switch (info->ecc_opt) {
+               case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
+               case OMAP_ECC_BCH8_CODE_HW:
+                       bch_val1 = readl(gpmc_regs->gpmc_bch_result0[i]);
+                       bch_val2 = readl(gpmc_regs->gpmc_bch_result1[i]);
+                       bch_val3 = readl(gpmc_regs->gpmc_bch_result2[i]);
+                       bch_val4 = readl(gpmc_regs->gpmc_bch_result3[i]);
+                       *ecc_code++ = (bch_val4 & 0xFF);
+                       *ecc_code++ = ((bch_val3 >> 24) & 0xFF);
+                       *ecc_code++ = ((bch_val3 >> 16) & 0xFF);
+                       *ecc_code++ = ((bch_val3 >> 8) & 0xFF);
+                       *ecc_code++ = (bch_val3 & 0xFF);
+                       *ecc_code++ = ((bch_val2 >> 24) & 0xFF);
+                       *ecc_code++ = ((bch_val2 >> 16) & 0xFF);
+                       *ecc_code++ = ((bch_val2 >> 8) & 0xFF);
+                       *ecc_code++ = (bch_val2 & 0xFF);
+                       *ecc_code++ = ((bch_val1 >> 24) & 0xFF);
+                       *ecc_code++ = ((bch_val1 >> 16) & 0xFF);
+                       *ecc_code++ = ((bch_val1 >> 8) & 0xFF);
+                       *ecc_code++ = (bch_val1 & 0xFF);
+                       break;
+               case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW:
+               case OMAP_ECC_BCH4_CODE_HW:
+                       bch_val1 = readl(gpmc_regs->gpmc_bch_result0[i]);
+                       bch_val2 = readl(gpmc_regs->gpmc_bch_result1[i]);
+                       *ecc_code++ = ((bch_val2 >> 12) & 0xFF);
+                       *ecc_code++ = ((bch_val2 >> 4) & 0xFF);
+                       *ecc_code++ = ((bch_val2 & 0xF) << 4) |
+                               ((bch_val1 >> 28) & 0xF);
+                       *ecc_code++ = ((bch_val1 >> 20) & 0xFF);
+                       *ecc_code++ = ((bch_val1 >> 12) & 0xFF);
+                       *ecc_code++ = ((bch_val1 >> 4) & 0xFF);
+                       *ecc_code++ = ((bch_val1 & 0xF) << 4);
+                       break;
+               case OMAP_ECC_BCH16_CODE_HW:
+                       val = readl(gpmc_regs->gpmc_bch_result6[i]);
+                       ecc_code[0]  = ((val >>  8) & 0xFF);
+                       ecc_code[1]  = ((val >>  0) & 0xFF);
+                       val = readl(gpmc_regs->gpmc_bch_result5[i]);
+                       ecc_code[2]  = ((val >> 24) & 0xFF);
+                       ecc_code[3]  = ((val >> 16) & 0xFF);
+                       ecc_code[4]  = ((val >>  8) & 0xFF);
+                       ecc_code[5]  = ((val >>  0) & 0xFF);
+                       val = readl(gpmc_regs->gpmc_bch_result4[i]);
+                       ecc_code[6]  = ((val >> 24) & 0xFF);
+                       ecc_code[7]  = ((val >> 16) & 0xFF);
+                       ecc_code[8]  = ((val >>  8) & 0xFF);
+                       ecc_code[9]  = ((val >>  0) & 0xFF);
+                       val = readl(gpmc_regs->gpmc_bch_result3[i]);
+                       ecc_code[10] = ((val >> 24) & 0xFF);
+                       ecc_code[11] = ((val >> 16) & 0xFF);
+                       ecc_code[12] = ((val >>  8) & 0xFF);
+                       ecc_code[13] = ((val >>  0) & 0xFF);
+                       val = readl(gpmc_regs->gpmc_bch_result2[i]);
+                       ecc_code[14] = ((val >> 24) & 0xFF);
+                       ecc_code[15] = ((val >> 16) & 0xFF);
+                       ecc_code[16] = ((val >>  8) & 0xFF);
+                       ecc_code[17] = ((val >>  0) & 0xFF);
+                       val = readl(gpmc_regs->gpmc_bch_result1[i]);
+                       ecc_code[18] = ((val >> 24) & 0xFF);
+                       ecc_code[19] = ((val >> 16) & 0xFF);
+                       ecc_code[20] = ((val >>  8) & 0xFF);
+                       ecc_code[21] = ((val >>  0) & 0xFF);
+                       val = readl(gpmc_regs->gpmc_bch_result0[i]);
+                       ecc_code[22] = ((val >> 24) & 0xFF);
+                       ecc_code[23] = ((val >> 16) & 0xFF);
+                       ecc_code[24] = ((val >>  8) & 0xFF);
+                       ecc_code[25] = ((val >>  0) & 0xFF);
+                       break;
+               default:
+                       return -EINVAL;
+               }
+
+               /* ECC scheme specific syndrome customizations */
+               switch (info->ecc_opt) {
+               case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW:
+                       /* Add constant polynomial to remainder, so that
+                        * ECC of blank pages results in 0x0 on reading back */
+                       for (j = 0; j < eccbytes; j++)
+                               ecc_calc[j] ^= bch4_polynomial[j];
+                       break;
+               case OMAP_ECC_BCH4_CODE_HW:
+                       /* Set  8th ECC byte as 0x0 for ROM compatibility */
+                       ecc_calc[eccbytes - 1] = 0x0;
+                       break;
+               case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
+                       /* Add constant polynomial to remainder, so that
+                        * ECC of blank pages results in 0x0 on reading back */
+                       for (j = 0; j < eccbytes; j++)
+                               ecc_calc[j] ^= bch8_polynomial[j];
+                       break;
+               case OMAP_ECC_BCH8_CODE_HW:
+                       /* Set 14th ECC byte as 0x0 for ROM compatibility */
+                       ecc_calc[eccbytes - 1] = 0x0;
+                       break;
+               case OMAP_ECC_BCH16_CODE_HW:
+                       break;
+               default:
+                       return -EINVAL;
+               }
 
-               ecc_calc += eccbytes;
+       ecc_calc += eccbytes;
        }
 
        return 0;
@@ -1571,7 +1527,7 @@ static int omap_write_page_bch(struct mt
        chip->write_buf(mtd, buf, mtd->writesize);
 
        /* Update ecc vector from GPMC result registers */
-       omap_calculate_ecc_bch_multi(mtd, buf, &ecc_calc[0]);
+       chip->ecc.calculate(mtd, buf, &ecc_calc[0]);
 
        for (i = 0; i < chip->ecc.total; i++)
                chip->oob_poi[eccpos[i]] = ecc_calc[i];
@@ -1582,72 +1538,6 @@ static int omap_write_page_bch(struct mt
 }
 
 /**
- * omap_write_subpage_bch - BCH hardware ECC based subpage write
- * @mtd:       mtd info structure
- * @chip:      nand chip info structure
- * @offset:    column address of subpage within the page
- * @data_len:  data length
- * @buf:       data buffer
- * @oob_required: must write chip->oob_poi to OOB
- * @page: page number to write
- *
- * OMAP optimized subpage write method.
- */
-static int omap_write_subpage_bch(struct mtd_info *mtd,
-                                 struct nand_chip *chip, u32 offset,
-                                 u32 data_len, const u8 *buf,
-                                 int oob_required, int page)
-{
-       u8 *ecc_calc = chip->buffers->ecccalc;
-       int ecc_size      = chip->ecc.size;
-       int ecc_bytes     = chip->ecc.bytes;
-       int ecc_steps     = chip->ecc.steps;
-       u32 start_step = offset / ecc_size;
-       u32 end_step   = (offset + data_len - 1) / ecc_size;
-       int step, ret = 0;
-
-       /*
-        * Write entire page at one go as it would be optimal
-        * as ECC is calculated by hardware.
-        * ECC is calculated for all subpages but we choose
-        * only what we want.
-        */
-
-       /* Enable GPMC ECC engine */
-       chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
-
-       /* Write data */
-       chip->write_buf(mtd, buf, mtd->writesize);
-
-       for (step = 0; step < ecc_steps; step++) {
-               /* mask ECC of un-touched subpages by padding 0xFF */
-               if (step < start_step || step > end_step)
-                       memset(ecc_calc, 0xff, ecc_bytes);
-               else
-                       ret = _omap_calculate_ecc_bch(mtd, buf, ecc_calc, step);
-
-               if (ret)
-                       return ret;
-
-               buf += ecc_size;
-               ecc_calc += ecc_bytes;
-       }
-
-       /* copy calculated ECC for whole page to chip->buffer->oob */
-       /* this include masked-value(0xFF) for unwritten subpages */
-       ecc_calc = chip->buffers->ecccalc;
-       ret = mtd_ooblayout_set_eccbytes(mtd, ecc_calc, chip->oob_poi, 0,
-                                        chip->ecc.total);
-       if (ret)
-               return ret;
-
-       /* write OOB buffer to NAND device */
-       chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
-
-       return 0;
-}
-
-/**
  * omap_read_page_bch - BCH ecc based page read function for entire page
  * @mtd:               mtd info structure
  * @chip:              nand chip info structure
@@ -1684,7 +1574,7 @@ static int omap_read_page_bch(struct mtd
        chip->read_buf(mtd, oob, chip->ecc.total);
 
        /* Calculate ecc bytes */
-       omap_calculate_ecc_bch_multi(mtd, buf, ecc_calc);
+       chip->ecc.calculate(mtd, buf, ecc_calc);
 
        memcpy(ecc_code, &chip->oob_poi[eccpos[0]], chip->ecc.total);
 
@@ -1933,7 +1823,7 @@ static int omap_nand_probe(struct platfo
                nand_chip->ecc.strength         = 4;
                nand_chip->ecc.hwctl            = omap_enable_hwecc_bch;
                nand_chip->ecc.correct          = nand_bch_correct_data;
-               nand_chip->ecc.calculate        = omap_calculate_ecc_bch_sw;
+               nand_chip->ecc.calculate        = omap_calculate_ecc_bch;
                /* define ECC layout */
                ecclayout->eccbytes             = nand_chip->ecc.bytes *
                                                        (mtd->writesize /
@@ -1973,9 +1863,9 @@ static int omap_nand_probe(struct platfo
                nand_chip->ecc.strength         = 4;
                nand_chip->ecc.hwctl            = omap_enable_hwecc_bch;
                nand_chip->ecc.correct          = omap_elm_correct_data;
+               nand_chip->ecc.calculate        = omap_calculate_ecc_bch;
                nand_chip->ecc.read_page        = omap_read_page_bch;
                nand_chip->ecc.write_page       = omap_write_page_bch;
-               nand_chip->ecc.write_subpage    = omap_write_subpage_bch;
                /* define ECC layout */
                ecclayout->eccbytes             = nand_chip->ecc.bytes *
                                                        (mtd->writesize /
@@ -2008,7 +1898,7 @@ static int omap_nand_probe(struct platfo
                nand_chip->ecc.strength         = 8;
                nand_chip->ecc.hwctl            = omap_enable_hwecc_bch;
                nand_chip->ecc.correct          = nand_bch_correct_data;
-               nand_chip->ecc.calculate        = omap_calculate_ecc_bch_sw;
+               nand_chip->ecc.calculate        = omap_calculate_ecc_bch;
                /* define ECC layout */
                ecclayout->eccbytes             = nand_chip->ecc.bytes *
                                                        (mtd->writesize /
@@ -2049,9 +1939,9 @@ static int omap_nand_probe(struct platfo
                nand_chip->ecc.strength         = 8;
                nand_chip->ecc.hwctl            = omap_enable_hwecc_bch;
                nand_chip->ecc.correct          = omap_elm_correct_data;
+               nand_chip->ecc.calculate        = omap_calculate_ecc_bch;
                nand_chip->ecc.read_page        = omap_read_page_bch;
                nand_chip->ecc.write_page       = omap_write_page_bch;
-               nand_chip->ecc.write_subpage    = omap_write_subpage_bch;
                /* This ECC scheme requires ELM H/W block */
                err = is_elm_present(info, pdata->elm_of_node, BCH8_ECC);
                if (err < 0) {
@@ -2084,9 +1974,9 @@ static int omap_nand_probe(struct platfo
                nand_chip->ecc.strength         = 16;
                nand_chip->ecc.hwctl            = omap_enable_hwecc_bch;
                nand_chip->ecc.correct          = omap_elm_correct_data;
+               nand_chip->ecc.calculate        = omap_calculate_ecc_bch;
                nand_chip->ecc.read_page        = omap_read_page_bch;
                nand_chip->ecc.write_page       = omap_write_page_bch;
-               nand_chip->ecc.write_subpage    = omap_write_subpage_bch;
                /* This ECC scheme requires ELM H/W block */
                err = is_elm_present(info, pdata->elm_of_node, BCH16_ECC);
                if (err < 0) {

Reply via email to