]> rtime.felk.cvut.cz Git - zynq/linux.git/commitdiff
mtd: spi-nor: Fix locking/unlocking when BP3 is used
authorJesper B. Christensen <jesper.christensen@cobham.com>
Mon, 9 Mar 2015 13:45:08 +0000 (14:45 +0100)
committerMichal Simek <michal.simek@xilinx.com>
Wed, 22 Apr 2015 12:31:28 +0000 (14:31 +0200)
Fix status register parsing error when 3rd block protect bit
is used.

Signed-off-by: Jesper B. Christensen <jesper.christensen@cobham.com>
Reviewed-by: Harini Katakam <harinik@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
drivers/mtd/spi-nor/spi-nor.c
include/linux/mtd/spi-nor.h

index 40c694ff9afa87a0e1622f700494a62b557c93fa..42c5477694b45ac425ac30f69dde72e4424c3d8f 100644 (file)
@@ -594,6 +594,18 @@ static int write_sr_modify_protection(struct spi_nor *nor, uint8_t status,
        return 0;
 }
 
+static uint8_t bp_bits_from_sr(struct spi_nor *nor, uint8_t status)
+{
+    uint8_t ret;
+
+    ret = (((status) & SR_BP_BIT_MASK) >> SR_BP_BIT_OFFSET);
+    if (nor->jedec_id == 0x20) {
+        ret |= ((status & SR_BP3) >> (SR_BP_BIT_OFFSET + 1));
+    }
+
+    return ret;
+}
+
 static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 {
        struct spi_nor *nor = mtd_to_spi_nor(mtd);
@@ -627,7 +639,7 @@ static int spi_nor_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
        lock_bits = min_protected_area_including_offset(nor, offset);
 
        /* Only modify protection if it will not unlock other areas */
-       if (lock_bits > BP_BITS_FROM_SR(status))
+       if (lock_bits > bp_bits_from_sr(nor, status))
                ret = write_sr_modify_protection(nor, status, lock_bits);
 
 err:
@@ -668,7 +680,7 @@ static int spi_nor_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
        lock_bits = min_protected_area_including_offset(nor, offset+len) - 1;
 
        /* Only modify protection if it will not lock other areas */
-       if (lock_bits < BP_BITS_FROM_SR(status))
+       if (lock_bits < bp_bits_from_sr(nor, status))
                ret = write_sr_modify_protection(nor, status, lock_bits);
 
 err:
@@ -694,7 +706,7 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
        status = read_sr(nor);
 
        protected_area_start = get_protected_area_start(nor,
-                                               BP_BITS_FROM_SR(status));
+                                               bp_bits_from_sr(nor, status));
        if (offset >= protected_area_start)
                ret = MTD_IS_LOCKED;
        else if (offset+len < protected_area_start)
index ebf10ade8ca0c03de00f21240787287f65a13521..707bf002202454c05faa13016129f4c3d74adf6e 100644 (file)
@@ -76,8 +76,6 @@
 /* Bit to determine whether protection starts from top or bottom */
 #define SR_BP_TB               0x20
 
-#define BP_BITS_FROM_SR(sr)    (((sr) & SR_BP_BIT_MASK) >> SR_BP_BIT_OFFSET)
-
 /* Highest resolution of sector locking */
 #define M25P_MAX_LOCKABLE_SECTORS      64