+int flash_unlock_address_range(struct target *target, uint32_t addr, uint32_t length)
+{
+ /* By default, pad to sector boundaries ... the real issue here
+ * is that our (only) caller *permanently* removes protection,
+ * and doesn't restore it.
+ */
+ return flash_iterate_address_range(target, "unprotect",
+ addr, length, true, &flash_driver_unprotect);
+}
+
+static int compare_section(const void *a, const void *b)
+{
+ struct imagesection *b1, *b2;
+ b1 = *((struct imagesection **)a);
+ b2 = *((struct imagesection **)b);
+
+ if (b1->base_address == b2->base_address)
+ return 0;
+ else if (b1->base_address > b2->base_address)
+ return 1;
+ else
+ return -1;
+}
+
+/**
+ * Get aligned start address of a flash write region
+ */
+target_addr_t flash_write_align_start(struct flash_bank *bank, target_addr_t addr)
+{
+ if (addr < bank->base || addr >= bank->base + bank->size
+ || bank->write_start_alignment <= 1)
+ return addr;
+
+ if (bank->write_start_alignment == FLASH_WRITE_ALIGN_SECTOR) {
+ uint32_t offset = addr - bank->base;
+ uint32_t aligned = 0;
+ int sect;
+ for (sect = 0; sect < bank->num_sectors; sect++) {
+ if (bank->sectors[sect].offset > offset)
+ break;
+
+ aligned = bank->sectors[sect].offset;
+ }
+ return bank->base + aligned;
+ }
+
+ return addr & ~(bank->write_start_alignment - 1);
+}
+
+/**
+ * Get aligned end address of a flash write region
+ */
+target_addr_t flash_write_align_end(struct flash_bank *bank, target_addr_t addr)
+{
+ if (addr < bank->base || addr >= bank->base + bank->size
+ || bank->write_end_alignment <= 1)
+ return addr;
+
+ if (bank->write_end_alignment == FLASH_WRITE_ALIGN_SECTOR) {
+ uint32_t offset = addr - bank->base;
+ uint32_t aligned = 0;
+ int sect;
+ for (sect = 0; sect < bank->num_sectors; sect++) {
+ aligned = bank->sectors[sect].offset + bank->sectors[sect].size - 1;
+ if (aligned >= offset)
+ break;
+ }
+ return bank->base + aligned;
+ }
+
+ return addr | (bank->write_end_alignment - 1);
+}
+
+/**
+ * Check if gap between sections is bigger than minimum required to discontinue flash write
+ */
+static bool flash_write_check_gap(struct flash_bank *bank,
+ target_addr_t addr1, target_addr_t addr2)