- New infrastructure is used to read status register (for chips that have 
support for struct status_register) throughout spi25.c.
- New infrastructure is used to prettyprint status register and write 
protection mode of status register (for chips that have support for struct 
status_register) in flashrom.c.
- New disable from access protection infrastructure is used (for chips that 
have support for struct wp) in flashrom.c

Signed-off-by: Hatim Kanchwala <ha...@hatimak.me>
---
 flashrom.c |  17 +++++--
 spi25.c    | 164 ++++++++++++++++++++++++++++++++++++++++++++++++-------------
 2 files changed, 145 insertions(+), 36 deletions(-)

diff --git a/flashrom.c b/flashrom.c
index 25e53f2..3e19cd6 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -26,26 +26,27 @@
 #ifndef __LIBPAYLOAD__
 #include <fcntl.h>
 #include <sys/stat.h>
 #endif
 #include <string.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <errno.h>
 #include <ctype.h>
 #include <getopt.h>
 #if HAVE_UTSNAME == 1
 #include <sys/utsname.h>
 #endif
+#include "chipdrivers.h"
 #include "flash.h"
 #include "flashchips.h"
 #include "programmer.h"
 #include "hwaccess.h"
 
 const char flashrom_version[] = FLASHROM_VERSION;
 const char *chip_to_probe = NULL;
 
 static enum programmer programmer = PROGRAMMER_INVALID;
 static const char *programmer_param = NULL;
 
 /*
  * Programmers supporting multiple buses can have differing size limits on
@@ -1250,29 +1251,37 @@ notfound:
        msg_cinfo("%s %s flash chip \"%s\" (%d kB, %s) ", force ? "Assuming" : 
"Found",
                  flash->chip->vendor, flash->chip->name, 
flash->chip->total_size, tmp);
        free(tmp);
 #if CONFIG_INTERNAL == 1
        if (programmer_table[programmer].map_flash_region == physmap)
                msg_cinfo("mapped at physical address 0x%0*" PRIxPTR ".\n",
                          PRIxPTR_WIDTH, flash->physical_memory);
        else
 #endif
                msg_cinfo("on %s.\n", programmer_table[programmer].name);
 
        /* Flash registers may more likely not be mapped if the chip was forced.
         * Lock info may be stored in registers, so avoid lock info printing. */
-       if (!force)
-               if (flash->chip->printlock)
+       if (!force) {
+               if (flash->chip->status_register) {
+                       for (enum status_register_num SRn = SR1; SRn <= 
top_status_register(flash); SRn++)
+                               flash->chip->status_register->print(flash, SRn);
+                       flash->chip->status_register->print_wp_mode(flash);
+                       if (flash->chip->wp)
+                               print_range_generic(flash);
+               } else if (flash->chip->printlock) {
                        flash->chip->printlock(flash);
+               }
+       }
 
        /* Get out of the way for later runs. */
        unmap_flash(flash);
 
        /* Return position of matching chip. */
        return chip - flashchips;
 }
 
 int read_buf_from_file(unsigned char *buf, unsigned long size,
                       const char *filename)
 {
 #ifdef __LIBPAYLOAD__
        msg_gerr("Error: No file I/O support in libpayload\n");
@@ -1988,27 +1997,29 @@ int doit(struct flashctx *flash, int force, const char 
*filename, int read_it,
        if (chip_safety_check(flash, force, read_it, write_it, erase_it, 
verify_it)) {
                msg_cerr("Aborting.\n");
                return 1;
        }
 
        if (normalize_romentries(flash)) {
                msg_cerr("Requested regions can not be handled. Aborting.\n");
                return 1;
        }
 
        /* Given the existence of read locks, we want to unlock for read,
         * erase and write.
         */
-       if (flash->chip->unlock)
+       if (flash->chip->wp)
+               flash->chip->wp->disable(flash);
+       else if (flash->chip->unlock)
                flash->chip->unlock(flash);
 
        if (read_it) {
                return read_flash_to_file(flash, filename);
        }
 
        oldcontents = malloc(size);
        if (!oldcontents) {
                msg_gerr("Out of memory!\n");
                exit(1);
        }
        /* Assume worst case: All bits are 0. */
        memset(oldcontents, 0x00, size);
diff --git a/spi25.c b/spi25.c
index af4b6db..51db4c8 100644
--- a/spi25.c
+++ b/spi25.c
@@ -341,29 +341,35 @@ int spi_chip_erase_60(struct flashctx *flash)
                .readcnt        = 0,
                .readarr        = NULL,
        }};
        
        result = spi_send_multicommand(flash, cmds);
        if (result) {
                msg_cerr("%s failed during command execution\n",
                        __func__);
                return result;
        }
        /* Wait until the Write-In-Progress bit is cleared.
         * This usually takes 1-85 s, so wait in 1 s steps.
         */
-       /* FIXME: We assume spi_read_status_register will never fail. */
-       while (spi_read_status_register(flash) & SPI_SR_WIP)
-               programmer_delay(1000 * 1000);
+       /* FIXME: We assume reading status register(s) will never fail. */
+       // TODO(hatim): Switch to newer infrastructure completely after 
integration
+       if (flash->chip->status_register) {
+               while (flash->chip->status_register->read(flash, SR1) & 
SPI_SR_WIP)
+                       programmer_delay(1000 * 1000);
+       } else {
+               while (spi_read_status_register(flash) & SPI_SR_WIP)
+                       programmer_delay(1000 * 1000);
+       }
        /* FIXME: Check the status register for errors. */
        return 0;
 }
 
 int spi_chip_erase_62(struct flashctx *flash)
 {
        int result;
        struct spi_command cmds[] = {
        {
                .writecnt       = JEDEC_WREN_OUTSIZE,
                .writearr       = (const unsigned char[]){ JEDEC_WREN },
                .readcnt        = 0,
                .readarr        = NULL,
@@ -378,29 +384,35 @@ int spi_chip_erase_62(struct flashctx *flash)
                .readcnt        = 0,
                .readarr        = NULL,
        }};
        
        result = spi_send_multicommand(flash, cmds);
        if (result) {
                msg_cerr("%s failed during command execution\n",
                        __func__);
                return result;
        }
        /* Wait until the Write-In-Progress bit is cleared.
         * This usually takes 2-5 s, so wait in 100 ms steps.
         */
-       /* FIXME: We assume spi_read_status_register will never fail. */
-       while (spi_read_status_register(flash) & SPI_SR_WIP)
-               programmer_delay(100 * 1000);
+       /* FIXME: We assume reading status register(s) will never fail. */
+       // TODO(hatim): Switch to newer infrastructure completely after 
integration
+       if (flash->chip->status_register) {
+               while (flash->chip->status_register->read(flash, SR1) & 
SPI_SR_WIP)
+                       programmer_delay(100 * 1000);
+       } else {
+               while (spi_read_status_register(flash) & SPI_SR_WIP)
+                       programmer_delay(100 * 1000);
+       }
        /* FIXME: Check the status register for errors. */
        return 0;
 }
 
 int spi_chip_erase_c7(struct flashctx *flash)
 {
        int result;
        struct spi_command cmds[] = {
        {
                .writecnt       = JEDEC_WREN_OUTSIZE,
                .writearr       = (const unsigned char[]){ JEDEC_WREN },
                .readcnt        = 0,
                .readarr        = NULL,
@@ -414,29 +426,35 @@ int spi_chip_erase_c7(struct flashctx *flash)
                .writearr       = NULL,
                .readcnt        = 0,
                .readarr        = NULL,
        }};
 
        result = spi_send_multicommand(flash, cmds);
        if (result) {
                msg_cerr("%s failed during command execution\n", __func__);
                return result;
        }
        /* Wait until the Write-In-Progress bit is cleared.
         * This usually takes 1-85 s, so wait in 1 s steps.
         */
-       /* FIXME: We assume spi_read_status_register will never fail. */
-       while (spi_read_status_register(flash) & SPI_SR_WIP)
-               programmer_delay(1000 * 1000);
+       /* FIXME: We assume reading status register(s) will never fail. */
+       // TODO(hatim): Switch to newer infrastructure completely after 
integration
+       if (flash->chip->status_register) {
+               while (flash->chip->status_register->read(flash, SR1) & 
SPI_SR_WIP)
+                       programmer_delay(1000 * 1000);
+       } else {
+               while (spi_read_status_register(flash) & SPI_SR_WIP)
+                       programmer_delay(1000 * 1000);
+       }
        /* FIXME: Check the status register for errors. */
        return 0;
 }
 
 int spi_block_erase_52(struct flashctx *flash, unsigned int addr,
                       unsigned int blocklen)
 {
        int result;
        struct spi_command cmds[] = {
        {
                .writecnt       = JEDEC_WREN_OUTSIZE,
                .writearr       = (const unsigned char[]){ JEDEC_WREN },
                .readcnt        = 0,
@@ -457,28 +475,35 @@ int spi_block_erase_52(struct flashctx *flash, unsigned 
int addr,
                .readcnt        = 0,
                .readarr        = NULL,
        }};
 
        result = spi_send_multicommand(flash, cmds);
        if (result) {
                msg_cerr("%s failed during command execution at address 0x%x\n",
                        __func__, addr);
                return result;
        }
        /* Wait until the Write-In-Progress bit is cleared.
         * This usually takes 100-4000 ms, so wait in 100 ms steps.
         */
-       while (spi_read_status_register(flash) & SPI_SR_WIP)
-               programmer_delay(100 * 1000);
+       /* FIXME: We assume reading status register(s) will never fail. */
+       // TODO(hatim): Switch to newer infrastructure completely after 
integration
+       if (flash->chip->status_register) {
+               while (flash->chip->status_register->read(flash, SR1) & 
SPI_SR_WIP)
+                       programmer_delay(100 * 1000);
+       } else {
+               while (spi_read_status_register(flash) & SPI_SR_WIP)
+                       programmer_delay(100 * 1000);
+       }
        /* FIXME: Check the status register for errors. */
        return 0;
 }
 
 /* Block size is usually
  * 32M (one die) for Micron
  */
 int spi_block_erase_c4(struct flashctx *flash, unsigned int addr, unsigned int 
blocklen)
 {
        int result;
        struct spi_command cmds[] = {
        {
                .writecnt       = JEDEC_WREN_OUTSIZE,
@@ -500,28 +525,35 @@ int spi_block_erase_c4(struct flashctx *flash, unsigned 
int addr, unsigned int b
                .writearr       = NULL,
                .readcnt        = 0,
                .readarr        = NULL,
        }};
 
        result = spi_send_multicommand(flash, cmds);
        if (result) {
                msg_cerr("%s failed during command execution at address 
0x%x\n", __func__, addr);
                return result;
        }
        /* Wait until the Write-In-Progress bit is cleared.
         * This usually takes 240-480 s, so wait in 500 ms steps.
         */
-       while (spi_read_status_register(flash) & SPI_SR_WIP)
-               programmer_delay(500 * 1000 * 1000);
+       /* FIXME: We assume reading status register(s) will never fail. */
+       // TODO(hatim): Switch to newer infrastructure completely after 
integration
+       if (flash->chip->status_register) {
+               while (flash->chip->status_register->read(flash, SR1) & 
SPI_SR_WIP)
+                       programmer_delay(500 * 1000);
+       } else {
+               while (spi_read_status_register(flash) & SPI_SR_WIP)
+                       programmer_delay(500 * 1000);
+       }
        /* FIXME: Check the status register for errors. */
        return 0;
 }
 
 /* Block size is usually
  * 64k for Macronix
  * 32k for SST
  * 4-32k non-uniform for EON
  */
 int spi_block_erase_d8(struct flashctx *flash, unsigned int addr,
                       unsigned int blocklen)
 {
        int result;
@@ -547,28 +579,35 @@ int spi_block_erase_d8(struct flashctx *flash, unsigned 
int addr,
                .readcnt        = 0,
                .readarr        = NULL,
        }};
 
        result = spi_send_multicommand(flash, cmds);
        if (result) {
                msg_cerr("%s failed during command execution at address 0x%x\n",
                        __func__, addr);
                return result;
        }
        /* Wait until the Write-In-Progress bit is cleared.
         * This usually takes 100-4000 ms, so wait in 100 ms steps.
         */
-       while (spi_read_status_register(flash) & SPI_SR_WIP)
-               programmer_delay(100 * 1000);
+       /* FIXME: We assume reading status register(s) will never fail. */
+       // TODO(hatim): Switch to newer infrastructure completely after 
integration
+       if (flash->chip->status_register) {
+               while (flash->chip->status_register->read(flash, SR1) & 
SPI_SR_WIP)
+                       programmer_delay(100 * 1000);
+       } else {
+               while (spi_read_status_register(flash) & SPI_SR_WIP)
+                       programmer_delay(100 * 1000);
+       }
        /* FIXME: Check the status register for errors. */
        return 0;
 }
 
 /* Block size is usually
  * 4k for PMC
  */
 int spi_block_erase_d7(struct flashctx *flash, unsigned int addr,
                       unsigned int blocklen)
 {
        int result;
        struct spi_command cmds[] = {
        {
@@ -592,28 +631,35 @@ int spi_block_erase_d7(struct flashctx *flash, unsigned 
int addr,
                .readcnt        = 0,
                .readarr        = NULL,
        }};
 
        result = spi_send_multicommand(flash, cmds);
        if (result) {
                msg_cerr("%s failed during command execution at address 0x%x\n",
                        __func__, addr);
                return result;
        }
        /* Wait until the Write-In-Progress bit is cleared.
         * This usually takes 100-4000 ms, so wait in 100 ms steps.
         */
-       while (spi_read_status_register(flash) & SPI_SR_WIP)
-               programmer_delay(100 * 1000);
+       /* FIXME: We assume reading status register(s) will never fail. */
+       // TODO(hatim): Switch to newer infrastructure completely after 
integration
+       if (flash->chip->status_register) {
+               while (flash->chip->status_register->read(flash, SR1) & 
SPI_SR_WIP)
+                       programmer_delay(100 * 1000);
+       } else {
+               while (spi_read_status_register(flash) & SPI_SR_WIP)
+                       programmer_delay(100 * 1000);
+       }
        /* FIXME: Check the status register for errors. */
        return 0;
 }
 
 /* Page erase (usually 256B blocks) */
 int spi_block_erase_db(struct flashctx *flash, unsigned int addr, unsigned int 
blocklen)
 {
        int result;
        struct spi_command cmds[] = {
        {
                .writecnt       = JEDEC_WREN_OUTSIZE,
                .writearr       = (const unsigned char[]){ JEDEC_WREN },
                .readcnt        = 0,
@@ -633,28 +679,35 @@ int spi_block_erase_db(struct flashctx *flash, unsigned 
int addr, unsigned int b
                .writearr       = NULL,
                .readcnt        = 0,
                .readarr        = NULL,
        } };
 
        result = spi_send_multicommand(flash, cmds);
        if (result) {
                msg_cerr("%s failed during command execution at address 
0x%x\n", __func__, addr);
                return result;
        }
 
        /* Wait until the Write-In-Progress bit is cleared.
         * This takes up to 20 ms usually (on worn out devices up to the 0.5s 
range), so wait in 1 ms steps. */
-       while (spi_read_status_register(flash) & SPI_SR_WIP)
-               programmer_delay(1 * 1000);
+       /* FIXME: We assume reading status register(s) will never fail. */
+       // TODO(hatim): Switch to newer infrastructure completely after 
integration
+       if (flash->chip->status_register) {
+               while (flash->chip->status_register->read(flash, SR1) & 
SPI_SR_WIP)
+                       programmer_delay(1 * 1000);
+       } else {
+               while (spi_read_status_register(flash) & SPI_SR_WIP)
+                       programmer_delay(1 * 1000);
+       }
        /* FIXME: Check the status register for errors. */
        return 0;
 }
 
 /* Sector size is usually 4k, though Macronix eliteflash has 64k */
 int spi_block_erase_20(struct flashctx *flash, unsigned int addr,
                       unsigned int blocklen)
 {
        int result;
        struct spi_command cmds[] = {
        {
                .writecnt       = JEDEC_WREN_OUTSIZE,
                .writearr       = (const unsigned char[]){ JEDEC_WREN },
@@ -676,28 +729,35 @@ int spi_block_erase_20(struct flashctx *flash, unsigned 
int addr,
                .readcnt        = 0,
                .readarr        = NULL,
        }};
 
        result = spi_send_multicommand(flash, cmds);
        if (result) {
                msg_cerr("%s failed during command execution at address 0x%x\n",
                        __func__, addr);
                return result;
        }
        /* Wait until the Write-In-Progress bit is cleared.
         * This usually takes 15-800 ms, so wait in 10 ms steps.
         */
-       while (spi_read_status_register(flash) & SPI_SR_WIP)
-               programmer_delay(10 * 1000);
+       /* FIXME: We assume reading status register(s) will never fail. */
+       // TODO(hatim): Switch to newer infrastructure completely after 
integration
+       if (flash->chip->status_register) {
+               while (flash->chip->status_register->read(flash, SR1) & 
SPI_SR_WIP)
+                       programmer_delay(10 * 1000);
+       } else {
+               while (spi_read_status_register(flash) & SPI_SR_WIP)
+                       programmer_delay(10 * 1000);
+       }
        /* FIXME: Check the status register for errors. */
        return 0;
 }
 
 int spi_block_erase_50(struct flashctx *flash, unsigned int addr, unsigned int 
blocklen)
 {
        int result;
        struct spi_command cmds[] = {
        {
 /*             .writecnt       = JEDEC_WREN_OUTSIZE,
                .writearr       = (const unsigned char[]){ JEDEC_WREN },
                .readcnt        = 0,
                .readarr        = NULL,
@@ -716,28 +776,35 @@ int spi_block_erase_50(struct flashctx *flash, unsigned 
int addr, unsigned int b
                .writearr       = NULL,
                .readcnt        = 0,
                .readarr        = NULL,
        }};
 
        result = spi_send_multicommand(flash, cmds);
        if (result) {
                msg_cerr("%s failed during command execution at address 
0x%x\n", __func__, addr);
                return result;
        }
        /* Wait until the Write-In-Progress bit is cleared.
         * This usually takes 10 ms, so wait in 1 ms steps.
         */
-       while (spi_read_status_register(flash) & SPI_SR_WIP)
-               programmer_delay(1 * 1000);
+       /* FIXME: We assume reading status register(s) will never fail. */
+       // TODO(hatim): Switch to newer infrastructure completely after 
integration
+       if (flash->chip->status_register) {
+               while (flash->chip->status_register->read(flash, SR1) & 
SPI_SR_WIP)
+                       programmer_delay(1 * 1000);
+       } else {
+               while (spi_read_status_register(flash) & SPI_SR_WIP)
+                       programmer_delay(1 * 1000);
+       }
        /* FIXME: Check the status register for errors. */
        return 0;
 }
 
 int spi_block_erase_81(struct flashctx *flash, unsigned int addr, unsigned int 
blocklen)
 {
        int result;
        struct spi_command cmds[] = {
        {
 /*             .writecnt       = JEDEC_WREN_OUTSIZE,
                .writearr       = (const unsigned char[]){ JEDEC_WREN },
                .readcnt        = 0,
                .readarr        = NULL,
@@ -756,28 +823,35 @@ int spi_block_erase_81(struct flashctx *flash, unsigned 
int addr, unsigned int b
                .writearr       = NULL,
                .readcnt        = 0,
                .readarr        = NULL,
        }};
 
        result = spi_send_multicommand(flash, cmds);
        if (result) {
                msg_cerr("%s failed during command execution at address 
0x%x\n", __func__, addr);
                return result;
        }
        /* Wait until the Write-In-Progress bit is cleared.
         * This usually takes 8 ms, so wait in 1 ms steps.
         */
-       while (spi_read_status_register(flash) & SPI_SR_WIP)
-               programmer_delay(1 * 1000);
+       /* FIXME: We assume reading status register(s) will never fail. */
+       // TODO(hatim): Switch to newer infrastructure completely after 
integration
+       if (flash->chip->status_register) {
+               while (flash->chip->status_register->read(flash, SR1) & 
SPI_SR_WIP)
+                       programmer_delay(1 * 1000);
+       } else {
+               while (spi_read_status_register(flash) & SPI_SR_WIP)
+                       programmer_delay(1 * 1000);
+       }
        /* FIXME: Check the status register for errors. */
        return 0;
 }
 
 int spi_block_erase_60(struct flashctx *flash, unsigned int addr,
                       unsigned int blocklen)
 {
        if ((addr != 0) || (blocklen != flash->chip->total_size * 1024)) {
                msg_cerr("%s called with incorrect arguments\n",
                        __func__);
                return -1;
        }
        return spi_chip_erase_60(flash);
@@ -1004,54 +1078,66 @@ int spi_write_chunked(struct flashctx *flash, const 
uint8_t *buf, unsigned int s
         * page as well, the loop condition uses <=.
         */
        for (i = start / page_size; i <= (start + len - 1) / page_size; i++) {
                /* Byte position of the first byte in the range in this page. */
                /* starthere is an offset to the base address of the chip. */
                starthere = max(start, i * page_size);
                /* Length of bytes in the range in this page. */
                lenhere = min(start + len, (i + 1) * page_size) - starthere;
                for (j = 0; j < lenhere; j += chunksize) {
                        towrite = min(chunksize, lenhere - j);
                        rc = spi_nbyte_program(flash, starthere + j, buf + 
starthere - start + j, towrite);
                        if (rc)
                                break;
-                       while (spi_read_status_register(flash) & SPI_SR_WIP)
-                               programmer_delay(10);
+                       // TODO(hatim): Switch to newer infrastructure 
completely after integration
+                       if (flash->chip->status_register) {
+                               while 
(flash->chip->status_register->read(flash, SR1) & SPI_SR_WIP)
+                                       programmer_delay(10);
+                       } else {
+                               while (spi_read_status_register(flash) & 
SPI_SR_WIP)
+                                       programmer_delay(10);
+                       }
                }
                if (rc)
                        break;
        }
 
        return rc;
 }
 
 /*
  * Program chip using byte programming. (SLOW!)
  * This is for chips which can only handle one byte writes
  * and for chips where memory mapped programming is impossible
  * (e.g. due to size constraints in IT87* for over 512 kB)
  */
 /* real chunksize is 1, logical chunksize is 1 */
 int spi_chip_write_1(struct flashctx *flash, const uint8_t *buf, unsigned int 
start, unsigned int len)
 {
        unsigned int i;
        int result = 0;
 
        for (i = start; i < start + len; i++) {
                result = spi_byte_program(flash, i, buf[i - start]);
                if (result)
                        return 1;
-               while (spi_read_status_register(flash) & SPI_SR_WIP)
-                       programmer_delay(10);
+               // TODO(hatim): Switch to newer infrastructure completely after 
integration
+               if (flash->chip->status_register) {
+                       while (flash->chip->status_register->read(flash, SR1) & 
SPI_SR_WIP)
+                               programmer_delay(10);
+               } else {
+                       while (spi_read_status_register(flash) & SPI_SR_WIP)
+                               programmer_delay(10);
+               }
        }
 
        return 0;
 }
 
 int default_spi_write_aai(struct flashctx *flash, const uint8_t *buf, unsigned 
int start, unsigned int len)
 {
        uint32_t pos = start;
        int result;
        unsigned char cmd[JEDEC_AAI_WORD_PROGRAM_CONT_OUTSIZE] = {
                JEDEC_AAI_WORD_PROGRAM,
        };
        struct spi_command cmds[] = {
@@ -1120,43 +1206,55 @@ int default_spi_write_aai(struct flashctx *flash, const 
uint8_t *buf, unsigned i
        if (len % 2) {
                msg_cerr("%s: total write length not even! Please report a "
                         "bug at flashrom@flashrom.org\n", __func__);
                /* Do not return an error for now. */
                //return SPI_GENERIC_ERROR;
        }
 
 
        result = spi_send_multicommand(flash, cmds);
        if (result != 0) {
                msg_cerr("%s failed during start command execution: %d\n", 
__func__, result);
                goto bailout;
        }
-       while (spi_read_status_register(flash) & SPI_SR_WIP)
-               programmer_delay(10);
+       // TODO(hatim): Switch to newer infrastructure completely after 
integration
+       if (flash->chip->status_register) {
+               while (flash->chip->status_register->read(flash, SR1) & 
SPI_SR_WIP)
+                       programmer_delay(10);
+       } else {
+               while (spi_read_status_register(flash) & SPI_SR_WIP)
+                       programmer_delay(10);
+       }
 
        /* We already wrote 2 bytes in the multicommand step. */
        pos += 2;
 
        /* Are there at least two more bytes to write? */
        while (pos < start + len - 1) {
                cmd[1] = buf[pos++ - start];
                cmd[2] = buf[pos++ - start];
                result = spi_send_command(flash, 
JEDEC_AAI_WORD_PROGRAM_CONT_OUTSIZE, 0, cmd, NULL);
                if (result != 0) {
                        msg_cerr("%s failed during followup AAI command 
execution: %d\n", __func__, result);
                        goto bailout;
                }
-               while (spi_read_status_register(flash) & SPI_SR_WIP)
-                       programmer_delay(10);
+               // TODO(hatim): Switch to newer infrastructure completely after 
integration
+               if (flash->chip->status_register) {
+                       while (flash->chip->status_register->read(flash, SR1) & 
SPI_SR_WIP)
+                               programmer_delay(10);
+               } else {
+                       while (spi_read_status_register(flash) & SPI_SR_WIP)
+                               programmer_delay(10);
+               }
        }
 
        /* Use WRDI to exit AAI mode. This needs to be done before issuing any 
other non-AAI command. */
        result = spi_write_disable(flash);
        if (result != 0) {
                msg_cerr("%s failed to disable AAI mode.\n", __func__);
                return SPI_GENERIC_ERROR;
        }
 
        /* Write remaining byte (if any). */
        if (pos < start + len) {
                if (spi_chip_write_1(flash, buf + pos - start, pos, pos % 2))
                        return SPI_GENERIC_ERROR;
-- 
2.7.4


_______________________________________________
flashrom mailing list
flashrom@flashrom.org
https://www.flashrom.org/mailman/listinfo/flashrom

Reply via email to