mtd: at91: extract hw ecc initialization to one function
authorJosh Wu <josh.wu@atmel.com>
Mon, 25 Jun 2012 10:07:43 +0000 (18:07 +0800)
committerDavid Woodhouse <David.Woodhouse@intel.com>
Fri, 6 Jul 2012 17:17:07 +0000 (18:17 +0100)
This patch moves hw ecc initialization code to one function.

Signed-off-by: Hong Xu <hong.xu@atmel.com>
Signed-off-by: Josh Wu <josh.wu@atmel.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
drivers/mtd/nand/atmel_nand.c

index 97ac6712bb1926c6ff8e31292cc3c362d4d53d9d..7a41a04beb87286efea71aae4ca142a46aec0641 100644 (file)
@@ -527,6 +527,66 @@ static int __devinit atmel_of_init_port(struct atmel_nand_host *host,
 }
 #endif
 
+static int __init atmel_hw_nand_init_params(struct platform_device *pdev,
+                                        struct atmel_nand_host *host)
+{
+       struct mtd_info *mtd = &host->mtd;
+       struct nand_chip *nand_chip = &host->nand_chip;
+       struct resource         *regs;
+
+       regs = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+       if (!regs) {
+               dev_err(host->dev,
+                       "Can't get I/O resource regs, use software ECC\n");
+               nand_chip->ecc.mode = NAND_ECC_SOFT;
+               return 0;
+       }
+
+       host->ecc = ioremap(regs->start, resource_size(regs));
+       if (host->ecc == NULL) {
+               dev_err(host->dev, "ioremap failed\n");
+               return -EIO;
+       }
+
+       /* ECC is calculated for the whole page (1 step) */
+       nand_chip->ecc.size = mtd->writesize;
+
+       /* set ECC page size and oob layout */
+       switch (mtd->writesize) {
+       case 512:
+               nand_chip->ecc.layout = &atmel_oobinfo_small;
+               ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_528);
+               break;
+       case 1024:
+               nand_chip->ecc.layout = &atmel_oobinfo_large;
+               ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_1056);
+               break;
+       case 2048:
+               nand_chip->ecc.layout = &atmel_oobinfo_large;
+               ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_2112);
+               break;
+       case 4096:
+               nand_chip->ecc.layout = &atmel_oobinfo_large;
+               ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_4224);
+               break;
+       default:
+               /* page size not handled by HW ECC */
+               /* switching back to soft ECC */
+               nand_chip->ecc.mode = NAND_ECC_SOFT;
+               return 0;
+       }
+
+       /* set up for HW ECC */
+       nand_chip->ecc.calculate = atmel_nand_calculate;
+       nand_chip->ecc.correct = atmel_nand_correct;
+       nand_chip->ecc.hwctl = atmel_nand_hwctl;
+       nand_chip->ecc.read_page = atmel_nand_read_page;
+       nand_chip->ecc.bytes = 4;
+       nand_chip->ecc.strength = 1;
+
+       return 0;
+}
+
 /*
  * Probe for the NAND device.
  */
@@ -535,7 +595,6 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
        struct atmel_nand_host *host;
        struct mtd_info *mtd;
        struct nand_chip *nand_chip;
-       struct resource *regs;
        struct resource *mem;
        struct mtd_part_parser_data ppdata = {};
        int res;
@@ -587,29 +646,6 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
                nand_chip->dev_ready = atmel_nand_device_ready;
 
        nand_chip->ecc.mode = host->board.ecc_mode;
-
-       regs = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-       if (!regs && nand_chip->ecc.mode == NAND_ECC_HW) {
-               printk(KERN_ERR "atmel_nand: can't get I/O resource "
-                               "regs\nFalling back on software ECC\n");
-               nand_chip->ecc.mode = NAND_ECC_SOFT;
-       }
-
-       if (nand_chip->ecc.mode == NAND_ECC_HW) {
-               host->ecc = ioremap(regs->start, resource_size(regs));
-               if (host->ecc == NULL) {
-                       printk(KERN_ERR "atmel_nand: ioremap failed\n");
-                       res = -EIO;
-                       goto err_ecc_ioremap;
-               }
-               nand_chip->ecc.calculate = atmel_nand_calculate;
-               nand_chip->ecc.correct = atmel_nand_correct;
-               nand_chip->ecc.hwctl = atmel_nand_hwctl;
-               nand_chip->ecc.read_page = atmel_nand_read_page;
-               nand_chip->ecc.bytes = 4;
-               nand_chip->ecc.strength = 1;
-       }
-
        nand_chip->chip_delay = 20;             /* 20us command delay time */
 
        if (host->board.bus_width_16)   /* 16-bit bus width */
@@ -661,40 +697,9 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
        }
 
        if (nand_chip->ecc.mode == NAND_ECC_HW) {
-               /* ECC is calculated for the whole page (1 step) */
-               nand_chip->ecc.size = mtd->writesize;
-
-               /* set ECC page size and oob layout */
-               switch (mtd->writesize) {
-               case 512:
-                       nand_chip->ecc.layout = &atmel_oobinfo_small;
-                       ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_528);
-                       break;
-               case 1024:
-                       nand_chip->ecc.layout = &atmel_oobinfo_large;
-                       ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_1056);
-                       break;
-               case 2048:
-                       nand_chip->ecc.layout = &atmel_oobinfo_large;
-                       ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_2112);
-                       break;
-               case 4096:
-                       nand_chip->ecc.layout = &atmel_oobinfo_large;
-                       ecc_writel(host->ecc, MR, ATMEL_ECC_PAGESIZE_4224);
-                       break;
-               default:
-                       /* page size not handled by HW ECC */
-                       /* switching back to soft ECC */
-                       nand_chip->ecc.mode = NAND_ECC_SOFT;
-                       nand_chip->ecc.calculate = NULL;
-                       nand_chip->ecc.correct = NULL;
-                       nand_chip->ecc.hwctl = NULL;
-                       nand_chip->ecc.read_page = NULL;
-                       nand_chip->ecc.postpad = 0;
-                       nand_chip->ecc.prepad = 0;
-                       nand_chip->ecc.bytes = 0;
-                       break;
-               }
+               res = atmel_hw_nand_init_params(pdev, host);
+               if (res != 0)
+                       goto err_hw_ecc;
        }
 
        /* second phase scan */
@@ -711,15 +716,15 @@ static int __init atmel_nand_probe(struct platform_device *pdev)
                return res;
 
 err_scan_tail:
+       if (host->ecc)
+               iounmap(host->ecc);
+err_hw_ecc:
 err_scan_ident:
 err_no_card:
        atmel_nand_disable(host);
        platform_set_drvdata(pdev, NULL);
        if (host->dma_chan)
                dma_release_channel(host->dma_chan);
-       if (host->ecc)
-               iounmap(host->ecc);
-err_ecc_ioremap:
        iounmap(host->io_base);
 err_nand_ioremap:
        kfree(host);