+/*
+ * This function gets the u-boot flash sector protection status
+ * (flash_info_t.protect[]) in sync with the sector protection
+ * status stored in hardware.
+ */
+static void flash_sync_real_protect (flash_info_t * info)
+{
+ int i;
+
+ switch (info->flash_id & FLASH_TYPEMASK) {
+ case FLASH_28F128J3A:
+ for (i = 0; i < info->sector_count; ++i) {
+ info->protect[i] = intel_sector_protected(info, i);
+ }
+ break;
+ case FLASH_AM040:
+ default:
+ /* no h/w protect support */
+ break;
+ }
+}
+
+
+/*
+ * checks if "sector" in bank "info" is protected. Should work on intel
+ * strata flash chips 28FxxxJ3x in 8-bit mode.
+ * Returns 1 if sector is protected (or timed-out while trying to read
+ * protection status), 0 if it is not.
+ */
+static unsigned char intel_sector_protected (flash_info_t *info, ushort sector)
+{
+ FPWV *addr;
+ FPWV *lock_conf_addr;
+ ulong start;
+ unsigned char ret;
+
+ /*
+ * first, wait for the WSM to be finished. The rationale for
+ * waiting for the WSM to become idle for at most
+ * CFG_FLASH_ERASE_TOUT is as follows. The WSM can be busy
+ * because of: (1) erase, (2) program or (3) lock bit
+ * configuration. So we just wait for the longest timeout of
+ * the (1)-(3), i.e. the erase timeout.
+ */
+
+ /* wait at least 35ns (W12) before issuing Read Status Register */
+ udelay(1);
+ addr = (FPWV *) info->start[sector];
+ *addr = (FPW) INTEL_STATUS;
+
+ start = get_timer (0);
+ while ((*addr & (FPW) INTEL_FINISHED) != (FPW) INTEL_FINISHED) {
+ if (get_timer (start) > CFG_FLASH_ERASE_TOUT) {
+ *addr = (FPW) INTEL_RESET; /* restore read mode */
+ printf("WSM busy too long, can't get prot status\n");
+ return 1;
+ }
+ }
+
+ /* issue the Read Identifier Codes command */
+ *addr = (FPW) INTEL_READID;
+
+ /* wait at least 35ns (W12) before reading */
+ udelay(1);
+
+ /* Intel example code uses offset of 4 for 8-bit flash */
+ lock_conf_addr = (FPWV *) info->start[sector] + 4;
+ ret = (*lock_conf_addr & (FPW) INTEL_PROTECT) ? 1 : 0;
+
+ /* put flash back in read mode */
+ *addr = (FPW) INTEL_RESET;
+
+ return ret;
+}
+
+
+/*
+ * Checks if "bank1" and "bank2" are on the same chip. Returns 1 if they
+ * are and 0 otherwise.
+ */
+static unsigned char same_chip_banks (int bank1, int bank2)
+{
+ unsigned char same_chip[CFG_MAX_FLASH_BANKS][CFG_MAX_FLASH_BANKS] = {
+ {1, 1, 0, 0},
+ {1, 1, 0, 0},
+ {0, 0, 1, 1},
+ {0, 0, 1, 1}
+ };
+ return same_chip[bank1][bank2];
+}
+
+