mtd: spi-nor: eliminate duplicate spi_nor_wait_till_{, fsr}_ready() code
authorBrian Norris <computersforpeace@gmail.com>
Wed, 10 Sep 2014 07:26:16 +0000 (00:26 -0700)
committerBrian Norris <computersforpeace@gmail.com>
Wed, 5 Nov 2014 10:01:32 +0000 (02:01 -0800)
These functions were near-carbon-copies due to a small per-flash quirk.
Let's add a new spi_nor::flags bitfield to support these types of
quirks.

Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Reviewed-by: Marek Vasut <marex@denx.de>
Cc: Graham Moore <grmoore@altera.com>
Cc: Huang Shijie <shijie8@gmail.com>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
drivers/mtd/spi-nor/spi-nor.c

index ea6516d120e75e3a9b3c550b8c5ad790da7ccca9..c66de2fc89d60749aec8d35ea7260c83c07820ff 100644 (file)
@@ -165,48 +165,51 @@ static inline int set_4byte(struct spi_nor *nor, u32 jedec_id, int enable)
                return nor->write_reg(nor, SPINOR_OP_BRWR, nor->cmd_buf, 1, 0);
        }
 }
-
-static int spi_nor_wait_till_ready(struct spi_nor *nor)
+static inline int spi_nor_sr_ready(struct spi_nor *nor)
 {
-       unsigned long deadline;
-       int sr;
-
-       deadline = jiffies + MAX_READY_WAIT_JIFFIES;
-
-       do {
-               cond_resched();
+       int sr = read_sr(nor);
+       if (sr < 0)
+               return sr;
+       else
+               return !(sr & SR_WIP);
+}
 
-               sr = read_sr(nor);
-               if (sr < 0)
-                       break;
-               else if (!(sr & SR_WIP))
-                       return 0;
-       } while (!time_after_eq(jiffies, deadline));
+static inline int spi_nor_fsr_ready(struct spi_nor *nor)
+{
+       int fsr = read_fsr(nor);
+       if (fsr < 0)
+               return fsr;
+       else
+               return fsr & FSR_READY;
+}
 
-       return -ETIMEDOUT;
+static int spi_nor_ready(struct spi_nor *nor)
+{
+       int sr, fsr;
+       sr = spi_nor_sr_ready(nor);
+       if (sr < 0)
+               return sr;
+       fsr = nor->flags & SNOR_F_USE_FSR ? spi_nor_fsr_ready(nor) : 1;
+       if (fsr < 0)
+               return fsr;
+       return sr && fsr;
 }
 
-static int spi_nor_wait_till_fsr_ready(struct spi_nor *nor)
+static int spi_nor_wait_till_ready(struct spi_nor *nor)
 {
        unsigned long deadline;
-       int sr;
-       int fsr;
+       int ret;
 
        deadline = jiffies + MAX_READY_WAIT_JIFFIES;
 
        do {
                cond_resched();
 
-               sr = read_sr(nor);
-               if (sr < 0) {
-                       break;
-               } else if (!(sr & SR_WIP)) {
-                       fsr = read_fsr(nor);
-                       if (fsr < 0)
-                               break;
-                       if (fsr & FSR_READY)
-                               return 0;
-               }
+               ret = spi_nor_ready(nor);
+               if (ret < 0)
+                       return ret;
+               if (ret)
+                       return 0;
        } while (!time_after_eq(jiffies, deadline));
 
        return -ETIMEDOUT;
@@ -986,9 +989,8 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
        else
                mtd->_write = spi_nor_write;
 
-       if ((info->flags & USE_FSR) &&
-           nor->wait_till_ready == spi_nor_wait_till_ready)
-               nor->wait_till_ready = spi_nor_wait_till_fsr_ready;
+       if (info->flags & USE_FSR)
+               nor->flags |= SNOR_F_USE_FSR;
 
 #ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS
        /* prefer "small sector" erase if possible */