More tightly integrated non-blocking variants of some CFI flash access
functions. Enable with CONFIG_SYS_FLASH_CFI_NONBLOCK
These can be useful to erase flash or write complete sectors of flash
during a serial data transfer for software updates.
Signed-off-by: Wolfgang Wegner w.weg...@astro-kom.de
---
Re-worked patch avoiding code duplication and fixing white-space as
well as line length errors I found while forwarding to next branch.
drivers/mtd/cfi_flash.c | 269 +++
include/flash.h |9 ++
2 files changed, 210 insertions(+), 68 deletions(-)
diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
index c611f6b..74fa75f 100644
--- a/drivers/mtd/cfi_flash.c
+++ b/drivers/mtd/cfi_flash.c
@@ -528,22 +528,30 @@ static int flash_is_busy (flash_info_t * info,
flash_sect_t sect)
}
/*---
- * wait for XSR.7 to be set. Time out with an error if it does not.
+ * check/wait for XSR.7 is set. When tout is nonzero, start timer, else check
+ * if time out value is reached.
* This routine does not set the flash to read-array mode.
*/
-static int flash_status_check (flash_info_t * info, flash_sect_t sector,
- ulong tout, char *prompt)
+static int flash_status_check_int (flash_info_t * info, flash_sect_t sector,
+ ulong tout, char *prompt, int nonblock)
{
- ulong start;
+ static ulong start;
+ static ulong stout;
#if CONFIG_SYS_HZ != 1000
tout *= CONFIG_SYS_HZ/1000;
#endif
- /* Wait for command completion */
- start = get_timer (0);
- while (flash_is_busy (info, sector)) {
- if (get_timer (start) tout) {
+ if (tout || (nonblock == 0)){
+ stout = tout;
+ start = get_timer (0);
+ }
+
+ /* Check for command completion */
+
+ while (flash_is_busy (info, sector))
+ {
+ if (get_timer (start) stout) {
printf (Flash %s timeout at address %lx data %lx\n,
prompt, info-start[sector],
flash_read_long (info, sector, 0));
@@ -551,22 +559,38 @@ static int flash_status_check (flash_info_t * info,
flash_sect_t sector,
return ERR_TIMOUT;
}
udelay (1); /* also triggers watchdog */
+ if(nonblock)
+ return ERR_BUSY;
}
return ERR_OK;
}
/*---
- * Wait for XSR.7 to be set, if it times out print an error, otherwise
- * do a full status check.
+ * wait for XSR.7 to be set. Time out with an error if it does not.
+ * This routine does not set the flash to read-array mode.
+ */
+static int flash_status_check (flash_info_t * info, flash_sect_t sector,
+ ulong tout, char *prompt)
+{
+ return flash_status_check_int (info, sector, tout, prompt, 0);
+}
+
+/*---
+ * Check for XSR.7 to be set, either waiting for it (0 == nonblock) or
+ * returning FLASH_BUSY (1 == nonblock). If timeout is reached, print an
+ * error;
*
- * This routine sets the flash to read-array mode.
+ * This routine sets the flash to read-array mode if blocking mode is
+ * enabled or if successful in non-blocking mode.
*/
-static int flash_full_status_check (flash_info_t * info, flash_sect_t sector,
- ulong tout, char *prompt)
+static int flash_full_status_check_int (flash_info_t * info, flash_sect_t
sector,
+ ulong tout, char *prompt, int nonblock)
{
int retcode;
- retcode = flash_status_check (info, sector, tout, prompt);
+ retcode = flash_status_check_int (info, sector, tout, prompt, nonblock);
+ if(retcode == ERR_BUSY)
+ return retcode;
switch (info-vendor) {
case CFI_CMDSET_INTEL_PROG_REGIONS:
case CFI_CMDSET_INTEL_EXTENDED:
@@ -603,6 +627,18 @@ static int flash_full_status_check (flash_info_t * info,
flash_sect_t sector,
}
/*---
+ * Wait for XSR.7 to be set, if it times out print an error, otherwise
+ * do a full status check.
+ *
+ * This routine sets the flash to read-array mode.
+ */
+static int flash_full_status_check (flash_info_t * info, flash_sect_t sector,
+ ulong tout, char *prompt)
+{
+ return flash_full_status_check_int (info, sector, tout, prompt, 0);
+}
+
+/*---
*/
static void flash_add_byte (flash_info_t * info, cfiword_t * cword, uchar c)
{
@@ -671,8 +707,8 @@ static flash_sect_t find_sector (flash_info_t * info, ulong