mtd: nand: pxa3xx: Use extended cmdfunc() only if needed
authorEzequiel Garcia <ezequiel.garcia@free-electrons.com>
Wed, 18 Dec 2013 21:44:09 +0000 (18:44 -0300)
committerBrian Norris <computersforpeace@gmail.com>
Fri, 3 Jan 2014 19:22:27 +0000 (11:22 -0800)
Currently, we have two different cmdfunc's implementations:
one for PXA3xx SoC variant and one for Armada 370/XP SoC variant.

The former is the legacy one, typically constrained to devices
with page sizes smaller or equal to the controller's FIFO buffer.
On the other side, the latter _only_ supports the so-called extended
command semantics, which allow to handle devices with larger
page sizes (4 KiB, 8 KiB, ...).

This means we currently don't support devices with smaller pages on the
A370/XP SoC. Fix it by first renaming the cmdfuncs variants, and then
make the choice based on device page size (and SoC variant), rather than
SoC variant alone.

While at it, add a check for page size, to make sure we don't allow larger
pages sizes on the PXA3xx variant.

Tested-by: Arnaud Ebalard <arno@natisbad.org>
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
drivers/mtd/nand/pxa3xx_nand.c

index 9828033721852f0f741b7c36894dc3026eb90d80..f722ba70aaac77f8ff541a071217a709cff4f9f2 100644 (file)
@@ -897,8 +897,8 @@ static int prepare_set_command(struct pxa3xx_nand_info *info, int command,
        return exec_cmd;
 }
 
-static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
-                               int column, int page_addr)
+static void nand_cmdfunc(struct mtd_info *mtd, unsigned command,
+                        int column, int page_addr)
 {
        struct pxa3xx_nand_host *host = mtd->priv;
        struct pxa3xx_nand_info *info = host->info_data;
@@ -945,9 +945,9 @@ static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command,
        info->state = STATE_IDLE;
 }
 
-static void armada370_nand_cmdfunc(struct mtd_info *mtd,
-                                  const unsigned command,
-                                  int column, int page_addr)
+static void nand_cmdfunc_extended(struct mtd_info *mtd,
+                                 const unsigned command,
+                                 int column, int page_addr)
 {
        struct pxa3xx_nand_host *host = mtd->priv;
        struct pxa3xx_nand_info *info = host->info_data;
@@ -1487,6 +1487,21 @@ KEEP_CONFIG:
                chip->bbt_md = &bbt_mirror_descr;
        }
 
+       /*
+        * If the page size is bigger than the FIFO size, let's check
+        * we are given the right variant and then switch to the extended
+        * (aka splitted) command handling,
+        */
+       if (mtd->writesize > PAGE_CHUNK_SIZE) {
+               if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370) {
+                       chip->cmdfunc = nand_cmdfunc_extended;
+               } else {
+                       dev_err(&info->pdev->dev,
+                               "unsupported page size on this variant\n");
+                       return -ENODEV;
+               }
+       }
+
        if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370)
                ret = armada370_ecc_init(info, &chip->ecc,
                                   chip->ecc_strength_ds,
@@ -1566,11 +1581,7 @@ static int alloc_nand_resource(struct platform_device *pdev)
                chip->read_buf          = pxa3xx_nand_read_buf;
                chip->write_buf         = pxa3xx_nand_write_buf;
                chip->options           |= NAND_NO_SUBPAGE_WRITE;
-
-               if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370)
-                       chip->cmdfunc = armada370_nand_cmdfunc;
-               else
-                       chip->cmdfunc = pxa3xx_nand_cmdfunc;
+               chip->cmdfunc           = nand_cmdfunc;
        }
 
        spin_lock_init(&chip->controller->lock);