]> rtime.felk.cvut.cz Git - zynq/linux.git/commitdiff
Xilinx: ARM: NAND: Clearing the interrupt in dev_ready function
authorNaveen Mamindlapalli <naveenm@xhd-epdswlin32re1.(none)>
Wed, 1 Dec 2010 08:44:11 +0000 (14:14 +0530)
committerJohn Linn <john.linn@xilinx.com>
Wed, 1 Dec 2010 15:21:28 +0000 (08:21 -0700)
The interrupt is cleared in the dev_ready function so that mtd subsystem
reads the correct NAND flash status. The code cleanup is done.

Signed-off-by: Naveen Mamindlapalli <naveenm@xilinx.com>
drivers/mtd/nand/xilinx_nandpss.c

index 78163759cd307ffce04e5ef2f016bf70f6ecc89c..6906893c0d596139a9d73f91ceb4f3f54b0f816c 100644 (file)
@@ -178,7 +178,7 @@ static struct nand_ecclayout nand_oob_16 = {
        .eccpos = {0, 1, 2},
        .oobfree = {
                {.offset = 8,
-                . length = 8}}
+                . length = 8} }
 };
 
 static struct nand_ecclayout nand_oob_64 = {
@@ -188,7 +188,7 @@ static struct nand_ecclayout nand_oob_64 = {
                   58, 59, 60, 61, 62, 63},
        .oobfree = {
                {.offset = 2,
-                .length = 50}}
+                .length = 50} }
 };
 
 /**
@@ -266,7 +266,9 @@ xnandpss_calculate_hwecc(struct mtd_info *mtd, const u8 *data, u8 *ecc_code)
                                ecc_code++;
                        }
                } else {
-                       printk(KERN_INFO "pl350: ecc status failed\n");
+                       /* TO DO */
+                       /* dev_warn(&pdev->dev, "pl350: ecc status failed\n");
+                       * */
                }
        }
        return 0;
@@ -328,10 +330,8 @@ int xnandpss_correct_data(struct mtd_info *mtd, unsigned char *buf,
                return 1;
        } else if (onehot(ecc_odd | ecc_even) == 1) {
                return 1; /* one error in parity */
-       }
-       else {
-               printk(KERN_ERR "xnandpss: uncorrectable error\r\n");
-               return -1;
+       } else {
+               return -1; /* Uncorrectable error */
        }
 }
 
@@ -518,8 +518,8 @@ void xnandpss_write_page_hwecc(struct mtd_info *mtd,
  * @chip:      nand chip info structure
  * @buf:       data buffer
  */
-static void xnandpss_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
-                                 const uint8_t *buf)
+static void xnandpss_write_page_swecc(struct mtd_info *mtd,
+                       struct nand_chip *chip, const uint8_t *buf)
 {
        int i, eccsize = chip->ecc.size;
        int eccbytes = chip->ecc.bytes;
@@ -543,6 +543,7 @@ static void xnandpss_write_page_swecc(struct mtd_info *mtd, struct nand_chip *ch
  * @mtd:       Pointer to the mtd info structure
  * @chip:      Pointer to the NAND chip info structure
  * @buf:       Pointer to the buffer to store read data
+ * @page:      page number to read
  *
  * This functions reads data and checks the data integrity by comparing hardware
  * generated ECC values and read ECC values from spare area.
@@ -621,8 +622,8 @@ int xnandpss_read_page_hwecc(struct mtd_info *mtd,
  * @buf:       buffer to store read data
  * @page:      page number to read
  */
-static int xnandpss_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
-                               uint8_t *buf, int page)
+static int xnandpss_read_page_swecc(struct mtd_info *mtd,
+               struct nand_chip *chip, uint8_t *buf, int page)
 {
        int i, eccsize = chip->ecc.size;
        int eccbytes = chip->ecc.bytes;
@@ -739,10 +740,6 @@ static void xnandpss_cmd_function(struct mtd_info *mtd, unsigned int command,
 
        /* Get the data phase address */
        end_cmd_valid = 0;
-#if 0
-       if (curr_cmd->end_cmd_valid == XNANDPSS_DATA_PHASE)
-               end_cmd_valid = 1;
-#endif
 
        data_phase_addr = (unsigned long __force)xnand->nand_base       |
                        (0x0 << CLEAR_CS_SHIFT)                         |
@@ -775,9 +772,12 @@ static void xnandpss_cmd_function(struct mtd_info *mtd, unsigned int command,
        else if (page_addr != -1)
                cmd_data = page_addr;
        /* Change read/write column, read id etc */
-       else if (column != -1)
+       else if (column != -1) {
+               /* Adjust columns for 16 bit bus width */
+               if (chip->options & NAND_BUSWIDTH_16)
+                       column >>= 1;
                cmd_data = column;
-       else
+       else
                ;
 
        xnandpss_write32(cmd_addr, cmd_data);
@@ -788,14 +788,12 @@ static void xnandpss_cmd_function(struct mtd_info *mtd, unsigned int command,
        }
 
        ndelay(100);
-#define READ_CMD_HACK
-#ifdef READ_CMD_HACK
+
        if (command == NAND_CMD_READ0) {
-               while(!chip->dev_ready(mtd));
-               //udelay(20);
+               while (!chip->dev_ready(mtd))
+                       ;
                return;
        }
-#endif
 }
 
 /**
@@ -876,7 +874,11 @@ static int xnandpss_device_ready(struct mtd_info *mtd)
 
        /* Check the raw_int_status1 bit */
        status = xnandpss_read32(xnand->smc_regs + XSMCPSS_MC_STATUS) & 0x40;
-       return status?1:0;
+       /* Clear the interrupt condition */
+       if (status)
+               xnandpss_write32((xnand->smc_regs + XSMCPSS_MC_CLR_CONFIG),
+                                       (1<<4));
+       return status ? 1 : 0;
 }
 
 /**
@@ -887,7 +889,7 @@ static int xnandpss_device_ready(struct mtd_info *mtd)
  *
  * returns:    0 on success or error value on failure
  **/
-static int __init xnandpss_probe(struct platform_device *pdev)
+static int __devinit xnandpss_probe(struct platform_device *pdev)
 {
        struct xnandpss_info *xnand;
        struct mtd_info *mtd;
@@ -976,7 +978,6 @@ static int __init xnandpss_probe(struct platform_device *pdev)
 
        /* Set the driver entry points for MTD */
        nand_chip->cmdfunc = xnandpss_cmd_function;
-       //nand_chip->dev_ready = NULL;
        nand_chip->dev_ready = xnandpss_device_ready;
        nand_chip->select_chip = xnandpss_select_chip;
 
@@ -1039,7 +1040,8 @@ static int __init xnandpss_probe(struct platform_device *pdev)
                        (XNANDPSS_ECC_CONFIG | ecc_page_size));
                break;
        default:
-               /* The software ECC routines won't work with the SMC controller */
+               /* The software ECC routines won't work with the
+                       SMC controller */
                nand_chip->ecc.mode = NAND_ECC_HW;
                nand_chip->ecc.calculate = nand_calculate_ecc;
                nand_chip->ecc.correct = nand_correct_data;
@@ -1075,16 +1077,18 @@ static int __init xnandpss_probe(struct platform_device *pdev)
        nr_parts = parse_mtd_partitions(mtd, part_probe_types,
                                        &xnand->parts, 0);
        if (nr_parts > 0) {
-               dev_info(&pdev->dev, "found %d partitions in command line", nr_parts);
+               dev_info(&pdev->dev, "found %d partitions in command line",
+                               nr_parts);
                add_mtd_partitions(mtd, xnand->parts, nr_parts);
                return 0;
        } else if (pdata->parts)
                add_mtd_partitions(&xnand->mtd, pdata->parts, pdata->nr_parts);
        else {
 #endif
-               dev_info(&pdev->dev, "Command line partition table is not available,\n"
-                               "or command line partition option is not enabled\n"
-                               "creating single partition on flash\n");
+               dev_info(&pdev->dev,
+                       "Command line partition table is not available\n"
+                       "or command line partition option is not enabled\n"
+                       "creating single partition on flash\n");
 #endif
                err = add_mtd_device(mtd);
 #ifdef CONFIG_MTD_CMDLINE_PARTS