@@ -1636,6 +1636,95 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor)
1636
1636
return 0 ;
1637
1637
}
1638
1638
1639
+ /**
1640
+ * spi_nor_clear_sr_bp() - clear the Status Register Block Protection bits.
1641
+ * @nor: pointer to a 'struct spi_nor'
1642
+ *
1643
+ * Read-modify-write function that clears the Block Protection bits from the
1644
+ * Status Register without affecting other bits.
1645
+ *
1646
+ * Return: 0 on success, -errno otherwise.
1647
+ */
1648
+ static int spi_nor_clear_sr_bp (struct spi_nor * nor )
1649
+ {
1650
+ int ret ;
1651
+ u8 mask = SR_BP2 | SR_BP1 | SR_BP0 ;
1652
+
1653
+ ret = read_sr (nor );
1654
+ if (ret < 0 ) {
1655
+ dev_err (nor -> dev , "error while reading status register\n" );
1656
+ return ret ;
1657
+ }
1658
+
1659
+ write_enable (nor );
1660
+
1661
+ ret = write_sr (nor , ret & ~mask );
1662
+ if (ret ) {
1663
+ dev_err (nor -> dev , "write to status register failed\n" );
1664
+ return ret ;
1665
+ }
1666
+
1667
+ ret = spi_nor_wait_till_ready (nor );
1668
+ if (ret )
1669
+ dev_err (nor -> dev , "timeout while writing status register\n" );
1670
+ return ret ;
1671
+ }
1672
+
1673
+ /**
1674
+ * spi_nor_spansion_clear_sr_bp() - clear the Status Register Block Protection
1675
+ * bits on spansion flashes.
1676
+ * @nor: pointer to a 'struct spi_nor'
1677
+ *
1678
+ * Read-modify-write function that clears the Block Protection bits from the
1679
+ * Status Register without affecting other bits. The function is tightly
1680
+ * coupled with the spansion_quad_enable() function. Both assume that the Write
1681
+ * Register with 16 bits, together with the Read Configuration Register (35h)
1682
+ * instructions are supported.
1683
+ *
1684
+ * Return: 0 on success, -errno otherwise.
1685
+ */
1686
+ static int spi_nor_spansion_clear_sr_bp (struct spi_nor * nor )
1687
+ {
1688
+ int ret ;
1689
+ u8 mask = SR_BP2 | SR_BP1 | SR_BP0 ;
1690
+ u8 sr_cr [2 ] = {0 };
1691
+
1692
+ /* Check current Quad Enable bit value. */
1693
+ ret = read_cr (nor );
1694
+ if (ret < 0 ) {
1695
+ dev_err (nor -> dev ,
1696
+ "error while reading configuration register\n" );
1697
+ return ret ;
1698
+ }
1699
+
1700
+ /*
1701
+ * When the configuration register Quad Enable bit is one, only the
1702
+ * Write Status (01h) command with two data bytes may be used.
1703
+ */
1704
+ if (ret & CR_QUAD_EN_SPAN ) {
1705
+ sr_cr [1 ] = ret ;
1706
+
1707
+ ret = read_sr (nor );
1708
+ if (ret < 0 ) {
1709
+ dev_err (nor -> dev ,
1710
+ "error while reading status register\n" );
1711
+ return ret ;
1712
+ }
1713
+ sr_cr [0 ] = ret & ~mask ;
1714
+
1715
+ ret = write_sr_cr (nor , sr_cr );
1716
+ if (ret )
1717
+ dev_err (nor -> dev , "16-bit write register failed\n" );
1718
+ return ret ;
1719
+ }
1720
+
1721
+ /*
1722
+ * If the Quad Enable bit is zero, use the Write Status (01h) command
1723
+ * with one data byte.
1724
+ */
1725
+ return spi_nor_clear_sr_bp (nor );
1726
+ }
1727
+
1639
1728
/* Used when the "_ext_id" is two bytes at most */
1640
1729
#define INFO (_jedec_id , _ext_id , _sector_size , _n_sectors , _flags ) \
1641
1730
.id = { \
@@ -3660,6 +3749,8 @@ static int spi_nor_init_params(struct spi_nor *nor,
3660
3749
default :
3661
3750
/* Kept only for backward compatibility purpose. */
3662
3751
params -> quad_enable = spansion_quad_enable ;
3752
+ if (nor -> clear_sr_bp )
3753
+ nor -> clear_sr_bp = spi_nor_spansion_clear_sr_bp ;
3663
3754
break ;
3664
3755
}
3665
3756
@@ -3912,17 +4003,13 @@ static int spi_nor_init(struct spi_nor *nor)
3912
4003
{
3913
4004
int err ;
3914
4005
3915
- /*
3916
- * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
3917
- * with the software protection bits set
3918
- */
3919
- if (JEDEC_MFR (nor -> info ) == SNOR_MFR_ATMEL ||
3920
- JEDEC_MFR (nor -> info ) == SNOR_MFR_INTEL ||
3921
- JEDEC_MFR (nor -> info ) == SNOR_MFR_SST ||
3922
- nor -> info -> flags & SPI_NOR_HAS_LOCK ) {
3923
- write_enable (nor );
3924
- write_sr (nor , 0 );
3925
- spi_nor_wait_till_ready (nor );
4006
+ if (nor -> clear_sr_bp ) {
4007
+ err = nor -> clear_sr_bp (nor );
4008
+ if (err ) {
4009
+ dev_err (nor -> dev ,
4010
+ "fail to clear block protection bits\n" );
4011
+ return err ;
4012
+ }
3926
4013
}
3927
4014
3928
4015
if (nor -> quad_enable ) {
@@ -4047,6 +4134,16 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
4047
4134
if (info -> flags & SPI_S3AN )
4048
4135
nor -> flags |= SNOR_F_READY_XSR_RDY ;
4049
4136
4137
+ /*
4138
+ * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
4139
+ * with the software protection bits set.
4140
+ */
4141
+ if (JEDEC_MFR (nor -> info ) == SNOR_MFR_ATMEL ||
4142
+ JEDEC_MFR (nor -> info ) == SNOR_MFR_INTEL ||
4143
+ JEDEC_MFR (nor -> info ) == SNOR_MFR_SST ||
4144
+ nor -> info -> flags & SPI_NOR_HAS_LOCK )
4145
+ nor -> clear_sr_bp = spi_nor_clear_sr_bp ;
4146
+
4050
4147
/* Parse the Serial Flash Discoverable Parameters table. */
4051
4148
ret = spi_nor_init_params (nor , & params );
4052
4149
if (ret )
0 commit comments