diff --git a/contrib/loaders/watchdog/Makefile b/contrib/loaders/watchdog/Makefile
index 623e74407c09a7407defd799f3d64adfe0d013af..ed6d8f4e555c80f203e42f40c8941594b3578182 100644
--- a/contrib/loaders/watchdog/Makefile
+++ b/contrib/loaders/watchdog/Makefile
@@ -6,7 +6,7 @@ ARM_OBJCOPY ?= $(ARM_CROSS_COMPILE)objcopy
 
 ARM_AFLAGS = -EL -mthumb
 
-arm: armv7m_kinetis_wdog.inc
+arm: armv7m_kinetis_wdog.inc armv7m_kinetis_wdog32.inc
 
 armv7m_%.elf: armv7m_%.s
 	$(ARM_AS) $(ARM_AFLAGS) $< -o $@
diff --git a/contrib/loaders/watchdog/armv7m_kinetis_wdog.inc b/contrib/loaders/watchdog/armv7m_kinetis_wdog.inc
index 4b6579e0ce4fcc1923cfadc20cf474cacd3a7b3c..317d084dddf5be62e57d9dd25dacd154816b301d 100644
--- a/contrib/loaders/watchdog/armv7m_kinetis_wdog.inc
+++ b/contrib/loaders/watchdog/armv7m_kinetis_wdog.inc
@@ -1,4 +1,3 @@
 /* Autogenerated with ../../../src/helper/bin2char.sh */
-0x04,0x4b,0x05,0x4a,0xda,0x81,0x05,0x4a,0xda,0x81,0x01,0x24,0x1a,0x88,0xa2,0x43,
-0x1a,0x80,0x06,0xe0,0x00,0x20,0x05,0x40,0x20,0xc5,0x00,0x00,0x28,0xd9,0x00,0x00,
-0x00,0x00,0x00,0xbe,
+0x04,0x4a,0xc2,0x81,0x04,0x4a,0xc2,0x81,0x01,0x24,0x02,0x88,0xa2,0x43,0x02,0x80,
+0x05,0xe0,0x00,0x00,0x20,0xc5,0x00,0x00,0x28,0xd9,0x00,0x00,0x00,0x00,0x00,0xbe,
diff --git a/contrib/loaders/watchdog/armv7m_kinetis_wdog.s b/contrib/loaders/watchdog/armv7m_kinetis_wdog.s
index bac924ab805dbac45f26fc8fae96577ae0dfea98..d7241927c96ff593a7def293e4b3db10bfad139d 100644
--- a/contrib/loaders/watchdog/armv7m_kinetis_wdog.s
+++ b/contrib/loaders/watchdog/armv7m_kinetis_wdog.s
@@ -19,7 +19,9 @@
 
 /*
 	Disable watchdog for Kinetis Kx and KVx
-	Parameters: none
+	Parameters:
+		r0 ... WDOG base (in)
+
 	Used instruction set should work on both Cortex-M4 and M0+
 */
 
@@ -28,7 +30,6 @@
         .cpu cortex-m0
 	.thumb
 
-WDOG_ADDR	= 0x40052000
 /* WDOG registers offsets */
 WDOG_STCTRLH	= 0
 WDOG_UNLOCK	= 0x0e
@@ -39,17 +40,16 @@ WDOG_KEY2	= 0xd928
 	.thumb_func
 start:
 /* WDOG_UNLOCK = 0xC520 */
-	ldr     r3, =WDOG_ADDR
 	ldr     r2, =WDOG_KEY1
-	strh    r2, [r3, WDOG_UNLOCK]
+	strh    r2, [r0, WDOG_UNLOCK]
 /* WDOG_UNLOCK = 0xD928 */
 	ldr     r2, =WDOG_KEY2
-	strh    r2, [r3, WDOG_UNLOCK]
+	strh    r2, [r0, WDOG_UNLOCK]
 /* WDOG_STCTRLH clear bit 0 */
 	movs	r4, #1
-	ldrh    r2, [r3, WDOG_STCTRLH]
+	ldrh    r2, [r0, WDOG_STCTRLH]
 	bics	r2, r4
-	strh    r2, [r3, WDOG_STCTRLH]
+	strh    r2, [r0, WDOG_STCTRLH]
 /* OpenOCD checks exit point address. Jump to the very end. */
 	b	done
 
diff --git a/contrib/loaders/watchdog/armv7m_kinetis_wdog32.inc b/contrib/loaders/watchdog/armv7m_kinetis_wdog32.inc
new file mode 100644
index 0000000000000000000000000000000000000000..4ee06ed1f4d3c21d01c53f42d0a1aa5aae704440
--- /dev/null
+++ b/contrib/loaders/watchdog/armv7m_kinetis_wdog32.inc
@@ -0,0 +1,5 @@
+/* Autogenerated with ../../../src/helper/bin2char.sh */
+0x02,0x68,0x08,0x4b,0x1a,0x42,0x08,0x4b,0x01,0xd0,0x43,0x60,0x02,0xe0,0x83,0x80,
+0x1b,0x0c,0x83,0x80,0x80,0x24,0xa2,0x43,0x20,0x24,0x22,0x43,0x02,0x60,0x03,0x4b,
+0x83,0x60,0x06,0xe0,0x00,0x20,0x00,0x00,0x20,0xc5,0x28,0xd9,0x00,0x04,0x00,0x00,
+0x00,0x00,0x00,0xbe,
diff --git a/contrib/loaders/watchdog/armv7m_kinetis_wdog32.s b/contrib/loaders/watchdog/armv7m_kinetis_wdog32.s
new file mode 100644
index 0000000000000000000000000000000000000000..bf58327e953621fd21a9ebdbb652e772c9f126dc
--- /dev/null
+++ b/contrib/loaders/watchdog/armv7m_kinetis_wdog32.s
@@ -0,0 +1,81 @@
+/***************************************************************************
+ *   Copyright (C) 2017 Tomas Vanek                                        *
+ *   vanekt@fbl.cz                                                         *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.                                        *
+ ***************************************************************************/
+
+/*
+	Disable watchdog, 32-bit version for newer Kinetis
+	Parameters:
+		r0 ... WDOG32 base (in)
+
+	Used instruction set should work on both Cortex-M4 and M0+
+*/
+
+	.text
+	.syntax unified
+        .cpu cortex-m0
+	.thumb
+
+/* WDOG registers offsets */
+WDOG_CS		= 0
+WDOG_CNT	= 4
+WDOG_TOVAL	= 8
+
+WDOG_KEY 	= 0xd928c520
+
+	.thumb_func
+start:
+/* test WDOG_CS bit CMD32EN */
+	ldr     r2, [r0, WDOG_CS]
+	ldr     r3, =0x2000
+	tst     r2, r3
+	ldr     r3, =WDOG_KEY
+	beq     cmd16
+
+/* WDOG_CNT = key */
+	str     r3, [r0, WDOG_CNT]
+	b       unlocked
+
+cmd16:
+/* WDOG_CNT = key, halfword by halfword */
+	strh    r3, [r0, WDOG_CNT]
+	lsrs    r3, r3, #16
+	strh    r3, [r0, WDOG_CNT]
+
+/* WDOG_CS: clear EN bit 7, set UPDATE bit 5 */
+unlocked:
+	movs    r4, #0x80
+	bics    r2, r4
+	movs    r4, #0x20
+	orrs    r2, r4
+	str     r2, [r0, WDOG_CS]
+/* All active WDOG registers have to be updated, set dummy timeout */
+/* WDOG_TOVAL = 0x400 */
+	ldr     r3, =0x400
+	str     r3, [r0, WDOG_TOVAL]
+/* OpenOCD checks exit point address. Jump to the very end. */
+	b       done
+
+	.pool
+
+/* Avoid padding at .text segment end. Otherwise exit point check fails. */
+	.skip	( . - start + 2) & 2, 0
+done:
+	bkpt    #0
+
+	.end
+
diff --git a/src/flash/nor/kinetis.c b/src/flash/nor/kinetis.c
index dc3dc45976b0f9066a01c95a96e5bdc65d58aac9..1f2383d00d4bce963ea3fd57a134e5704de35922 100644
--- a/src/flash/nor/kinetis.c
+++ b/src/flash/nor/kinetis.c
@@ -100,11 +100,18 @@
 #define SIM_SOPT1	0x40047000
 #define SIM_FCFG1	0x4004804c
 #define SIM_FCFG2	0x40048050
-#define WDOG_STCTRH	0x40052000
+#define SIM_COPC	0x40048100
+#define WDOG_BASE	0x40052000
+#define WDOG32_KE1X	0x40052000
+#define WDOG32_KL28	0x40076000
 #define SMC_PMCTRL	0x4007E001
 #define SMC_PMSTAT	0x4007E003
 #define MCM_PLACR	0xF000300C
 
+/* Offsets */
+#define WDOG_STCTRLH_OFFSET      0
+#define WDOG32_CS_OFFSET         0
+
 /* Values */
 #define PM_STAT_RUN		0x01
 #define PM_STAT_VLPR		0x04
@@ -270,13 +277,26 @@ struct kinetis_chip {
 		FS_PROGRAM_SECTOR = 1,
 		FS_PROGRAM_LONGWORD = 2,
 		FS_PROGRAM_PHRASE = 4,		/* Unsupported */
-		FS_INVALIDATE_CACHE_K = 8,	/* using FMC->PFB0CR/PFB01CR */
-		FS_INVALIDATE_CACHE_L = 0x10,	/* using MCM->PLACR */
-		FS_INVALIDATE_CACHE_MSCM = 0x20,
+
 		FS_NO_CMD_BLOCKSTAT = 0x40,
 		FS_WIDTH_256BIT = 0x80,
 	} flash_support;
 
+	enum {
+		KINETIS_CACHE_NONE,
+		KINETIS_CACHE_K,	/* invalidate using FMC->PFB0CR/PFB01CR */
+		KINETIS_CACHE_L,	/* invalidate using MCM->PLACR */
+		KINETIS_CACHE_MSCM,	/* devices like KE1xF, invalidate MSCM->OCMDR0 */
+	} cache_type;
+
+	enum {
+		KINETIS_WDOG_NONE,
+		KINETIS_WDOG_K,
+		KINETIS_WDOG_COP,
+		KINETIS_WDOG32_KE1X,
+		KINETIS_WDOG32_KL28,
+	} watchdog_type;
+
 	char name[40];
 
 	unsigned num_banks;
@@ -362,6 +382,7 @@ static bool create_banks;
 struct flash_driver kinetis_flash;
 static int kinetis_write_inner(struct flash_bank *bank, const uint8_t *buffer,
 			uint32_t offset, uint32_t count);
+static int kinetis_probe_chip(struct kinetis_chip *k_chip);
 static int kinetis_auto_probe(struct flash_bank *bank);
 
 
@@ -941,11 +962,53 @@ static int kinetis_create_missing_banks(struct kinetis_chip *k_chip)
 }
 
 
-/* Disable the watchdog on Kinetis devices */
-int kinetis_disable_wdog(struct target *target, uint32_t sim_sdid)
+static int kinetis_disable_wdog_algo(struct target *target, size_t code_size, const uint8_t *code, uint32_t wdog_base)
 {
 	struct working_area *wdog_algorithm;
 	struct armv7m_algorithm armv7m_info;
+	struct reg_param reg_params[1];
+	int retval;
+
+	if (target->state != TARGET_HALTED) {
+		LOG_ERROR("Target not halted");
+		return ERROR_TARGET_NOT_HALTED;
+	}
+
+	retval = target_alloc_working_area(target, code_size, &wdog_algorithm);
+	if (retval != ERROR_OK)
+		return retval;
+
+	retval = target_write_buffer(target, wdog_algorithm->address,
+			code_size, code);
+	if (retval == ERROR_OK) {
+		armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
+		armv7m_info.core_mode = ARM_MODE_THREAD;
+
+		init_reg_param(&reg_params[0], "r0", 32, PARAM_IN);
+		buf_set_u32(reg_params[0].value, 0, 32, wdog_base);
+
+		retval = target_run_algorithm(target, 0, NULL, 1, reg_params,
+			wdog_algorithm->address,
+			wdog_algorithm->address + code_size - 2,
+			500, &armv7m_info);
+
+		destroy_reg_param(&reg_params[0]);
+
+		if (retval != ERROR_OK)
+			LOG_ERROR("Error executing Kinetis WDOG unlock algorithm");
+	}
+
+	target_free_working_area(target, wdog_algorithm);
+
+	return retval;
+}
+
+/* Disable the watchdog on Kinetis devices
+ * Standard Kx WDOG peripheral checks timing and therefore requires to run algo.
+ */
+static int kinetis_disable_wdog_kx(struct target *target)
+{
+	const uint32_t wdog_base = WDOG_BASE;
 	uint16_t wdog;
 	int retval;
 
@@ -953,14 +1016,7 @@ int kinetis_disable_wdog(struct target *target, uint32_t sim_sdid)
 #include "../../../contrib/loaders/watchdog/armv7m_kinetis_wdog.inc"
 	};
 
-	/* Decide whether the connected device needs watchdog disabling.
-	 * Disable for all Kx and KVx devices, return if it is a KLx */
-
-	if ((sim_sdid & KINETIS_SDID_SERIESID_MASK) == KINETIS_SDID_SERIESID_KL)
-		return ERROR_OK;
-
-	/* The connected device requires watchdog disabling. */
-	retval = target_read_u16(target, WDOG_STCTRH, &wdog);
+	retval = target_read_u16(target, wdog_base + WDOG_STCTRLH_OFFSET, &wdog);
 	if (retval != ERROR_OK)
 		return retval;
 
@@ -968,60 +1024,116 @@ int kinetis_disable_wdog(struct target *target, uint32_t sim_sdid)
 		/* watchdog already disabled */
 		return ERROR_OK;
 	}
-	LOG_INFO("Disabling Kinetis watchdog (initial WDOG_STCTRLH = 0x%x)", wdog);
+	LOG_INFO("Disabling Kinetis watchdog (initial WDOG_STCTRLH = 0x%04" PRIx16 ")", wdog);
 
-	if (target->state != TARGET_HALTED) {
-		LOG_ERROR("Target not halted");
-		return ERROR_TARGET_NOT_HALTED;
-	}
+	retval = kinetis_disable_wdog_algo(target, sizeof(kinetis_unlock_wdog_code), kinetis_unlock_wdog_code, wdog_base);
+	if (retval != ERROR_OK)
+		return retval;
 
-	retval = target_alloc_working_area(target, sizeof(kinetis_unlock_wdog_code), &wdog_algorithm);
+	retval = target_read_u16(target, wdog_base + WDOG_STCTRLH_OFFSET, &wdog);
 	if (retval != ERROR_OK)
 		return retval;
 
-	retval = target_write_buffer(target, wdog_algorithm->address,
-			sizeof(kinetis_unlock_wdog_code), (uint8_t *)kinetis_unlock_wdog_code);
-	if (retval != ERROR_OK) {
-		target_free_working_area(target, wdog_algorithm);
+	LOG_INFO("WDOG_STCTRLH = 0x%04" PRIx16, wdog);
+	return (wdog & 0x1) ? ERROR_FAIL : ERROR_OK;
+}
+
+static int kinetis_disable_wdog32(struct target *target, uint32_t wdog_base)
+{
+	uint32_t wdog_cs;
+	int retval;
+
+	static const uint8_t kinetis_unlock_wdog_code[] = {
+#include "../../../contrib/loaders/watchdog/armv7m_kinetis_wdog32.inc"
+	};
+
+	retval = target_read_u32(target, wdog_base + WDOG32_CS_OFFSET, &wdog_cs);
+	if (retval != ERROR_OK)
 		return retval;
-	}
 
-	armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
-	armv7m_info.core_mode = ARM_MODE_THREAD;
+	if ((wdog_cs & 0x80) == 0)
+		return ERROR_OK; /* watchdog already disabled */
 
-	retval = target_run_algorithm(target, 0, NULL, 0, NULL, wdog_algorithm->address,
-			wdog_algorithm->address + (sizeof(kinetis_unlock_wdog_code) - 2),
-			10000, &armv7m_info);
+	LOG_INFO("Disabling Kinetis watchdog (initial WDOG_CS 0x%08" PRIx32 ")", wdog_cs);
 
+	retval = kinetis_disable_wdog_algo(target, sizeof(kinetis_unlock_wdog_code), kinetis_unlock_wdog_code, wdog_base);
 	if (retval != ERROR_OK)
-		LOG_ERROR("error executing kinetis wdog unlock algorithm");
+		return retval;
 
-	retval = target_read_u16(target, WDOG_STCTRH, &wdog);
+	retval = target_read_u32(target, wdog_base + WDOG32_CS_OFFSET, &wdog_cs);
 	if (retval != ERROR_OK)
 		return retval;
-	LOG_INFO("WDOG_STCTRLH = 0x%x", wdog);
 
-	target_free_working_area(target, wdog_algorithm);
+	if ((wdog_cs & 0x80) == 0)
+		return ERROR_OK; /* watchdog disabled successfully */
 
-	return retval;
+	LOG_ERROR("Cannot disable Kinetis watchdog (WDOG_CS 0x%08" PRIx32 "), issue 'reset init'", wdog_cs);
+	return ERROR_FAIL;
+}
+
+static int kinetis_disable_wdog(struct kinetis_chip *k_chip)
+{
+	struct target *target = k_chip->target;
+	uint8_t sim_copc;
+	int retval;
+
+	if (!k_chip->probed) {
+		retval = kinetis_probe_chip(k_chip);
+		if (retval != ERROR_OK)
+			return retval;
+	}
+
+	switch (k_chip->watchdog_type) {
+	case KINETIS_WDOG_K:
+		return kinetis_disable_wdog_kx(target);
+
+	case KINETIS_WDOG_COP:
+		retval = target_read_u8(target, SIM_COPC, &sim_copc);
+		if (retval != ERROR_OK)
+			return retval;
+
+		if ((sim_copc & 0xc) == 0)
+			return ERROR_OK; /* watchdog already disabled */
+
+		LOG_INFO("Disabling Kinetis watchdog (initial SIM_COPC 0x%02" PRIx8 ")", sim_copc);
+		retval = target_write_u8(target, SIM_COPC, sim_copc & ~0xc);
+		if (retval != ERROR_OK)
+			return retval;
+
+		retval = target_read_u8(target, SIM_COPC, &sim_copc);
+		if (retval != ERROR_OK)
+			return retval;
+
+		if ((sim_copc & 0xc) == 0)
+			return ERROR_OK; /* watchdog disabled successfully */
+
+		LOG_ERROR("Cannot disable Kinetis watchdog (SIM_COPC 0x%02" PRIx8 "), issue 'reset init'", sim_copc);
+		return ERROR_FAIL;
+
+	case KINETIS_WDOG32_KE1X:
+		return kinetis_disable_wdog32(target, WDOG32_KE1X);
+
+	case KINETIS_WDOG32_KL28:
+		return kinetis_disable_wdog32(target, WDOG32_KL28);
+
+	default:
+		return ERROR_OK;
+	}
 }
 
 COMMAND_HANDLER(kinetis_disable_wdog_handler)
 {
 	int result;
-	uint32_t sim_sdid;
 	struct target *target = get_current_target(CMD_CTX);
+	struct kinetis_chip *k_chip = kinetis_get_chip(target);
+
+	if (k_chip == NULL)
+		return ERROR_FAIL;
 
 	if (CMD_ARGC > 0)
 		return ERROR_COMMAND_SYNTAX_ERROR;
 
-	result = target_read_u32(target, SIM_SDID, &sim_sdid);
-	if (result != ERROR_OK) {
-		LOG_ERROR("Failed to read SIMSDID");
-		return result;
-	}
-
-	result = kinetis_disable_wdog(target, sim_sdid);
+	result = kinetis_disable_wdog(k_chip);
 	return result;
 }
 
@@ -1400,20 +1512,26 @@ static void kinetis_invalidate_flash_cache(struct kinetis_chip *k_chip)
 {
 	struct target *target = k_chip->target;
 
-	if (k_chip->flash_support & FS_INVALIDATE_CACHE_K)
+	switch (k_chip->cache_type) {
+	case KINETIS_CACHE_K:
 		target_write_u8(target, FMC_PFB01CR + 2, 0xf0);
 		/* Set CINV_WAY bits - request invalidate of all cache ways */
 		/* FMC_PFB0CR has same address and CINV_WAY bits as FMC_PFB01CR */
+		break;
 
-	else if (k_chip->flash_support & FS_INVALIDATE_CACHE_L)
+	case KINETIS_CACHE_L:
 		target_write_u8(target, MCM_PLACR + 1, 0x04);
 		/* set bit CFCC - Clear Flash Controller Cache */
+		break;
 
-	else if (k_chip->flash_support & FS_INVALIDATE_CACHE_MSCM)
+	case KINETIS_CACHE_MSCM:
 		target_write_u32(target, MSCM_OCMDR0, 0x30);
 		/* disable data prefetch and flash speculate */
+		break;
 
-	return;
+	default:
+		break;
+	}
 }
 
 
@@ -1647,7 +1765,7 @@ static int kinetis_write_inner(struct flash_bank *bank, const uint8_t *buffer,
 
 		uint32_t words_remaining = count / 4;
 
-		kinetis_disable_wdog(bank->target, k_chip->sim_sdid);
+		kinetis_disable_wdog(k_chip);
 
 		/* try using a block write */
 		result = kinetis_write_block(bank, buffer, offset, words_remaining);
@@ -1791,6 +1909,8 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
 	if ((k_chip->sim_sdid & (~KINETIS_SDID_K_SERIES_MASK)) == 0) {
 		/* older K-series MCU */
 		uint32_t mcu_type = k_chip->sim_sdid & KINETIS_K_SDID_TYPE_MASK;
+		k_chip->cache_type = KINETIS_CACHE_K;
+		k_chip->watchdog_type = KINETIS_WDOG_K;
 
 		switch (mcu_type) {
 		case KINETIS_K_SDID_K10_M50:
@@ -1799,7 +1919,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
 			k_chip->pflash_sector_size = 1<<10;
 			k_chip->nvm_sector_size = 1<<10;
 			num_blocks = 2;
-			k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
+			k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR;
 			break;
 		case KINETIS_K_SDID_K10_M72:
 		case KINETIS_K_SDID_K20_M72:
@@ -1812,7 +1932,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
 			k_chip->pflash_sector_size = 2<<10;
 			k_chip->nvm_sector_size = 1<<10;
 			num_blocks = 2;
-			k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
+			k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR;
 			k_chip->max_flash_prog_size = 1<<10;
 			break;
 		case KINETIS_K_SDID_K10_M100:
@@ -1828,7 +1948,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
 			k_chip->pflash_sector_size = 2<<10;
 			k_chip->nvm_sector_size = 2<<10;
 			num_blocks = 2;
-			k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
+			k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_PROGRAM_SECTOR;
 			break;
 		case KINETIS_K_SDID_K21_M120:
 		case KINETIS_K_SDID_K22_M120:
@@ -1837,7 +1957,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
 			k_chip->max_flash_prog_size = 1<<10;
 			k_chip->nvm_sector_size = 4<<10;
 			num_blocks = 2;
-			k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
+			k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
 			break;
 		case KINETIS_K_SDID_K10_M120:
 		case KINETIS_K_SDID_K20_M120:
@@ -1847,7 +1967,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
 			k_chip->pflash_sector_size = 4<<10;
 			k_chip->nvm_sector_size = 4<<10;
 			num_blocks = 4;
-			k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
+			k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
 			break;
 		default:
 			LOG_ERROR("Unsupported K-family FAMID");
@@ -1869,12 +1989,15 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
 		switch (k_chip->sim_sdid & KINETIS_SDID_SERIESID_MASK) {
 		case KINETIS_SDID_SERIESID_K:
 			use_nvm_marking = true;
+			k_chip->cache_type = KINETIS_CACHE_K;
+			k_chip->watchdog_type = KINETIS_WDOG_K;
+
 			switch (k_chip->sim_sdid & (KINETIS_SDID_FAMILYID_MASK | KINETIS_SDID_SUBFAMID_MASK)) {
 			case KINETIS_SDID_FAMILYID_K0X | KINETIS_SDID_SUBFAMID_KX2:
 				/* K02FN64, K02FN128: FTFA, 2kB sectors */
 				k_chip->pflash_sector_size = 2<<10;
 				num_blocks = 1;
-				k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_K;
+				k_chip->flash_support = FS_PROGRAM_LONGWORD;
 				cpu_mhz = 100;
 				break;
 
@@ -1890,7 +2013,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
 					/* MK24FN1M */
 					k_chip->pflash_sector_size = 4<<10;
 					num_blocks = 2;
-					k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
+					k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
 					k_chip->max_flash_prog_size = 1<<10;
 					subfamid = 4; /* errata 1N83J fix */
 					break;
@@ -1901,7 +2024,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
 					/* K22 with new-style SDID - smaller pflash with FTFA, 2kB sectors */
 					k_chip->pflash_sector_size = 2<<10;
 					/* autodetect 1 or 2 blocks */
-					k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_K;
+					k_chip->flash_support = FS_PROGRAM_LONGWORD;
 					break;
 				}
 				LOG_ERROR("Unsupported Kinetis K22 DIEID");
@@ -1912,12 +2035,12 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
 				if ((k_chip->sim_sdid & (KINETIS_SDID_DIEID_MASK)) == KINETIS_SDID_DIEID_K24FN256) {
 					/* K24FN256 - smaller pflash with FTFA */
 					num_blocks = 1;
-					k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_K;
+					k_chip->flash_support = FS_PROGRAM_LONGWORD;
 					break;
 				}
 				/* K24FN1M without errata 7534 */
 				num_blocks = 2;
-				k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
+				k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
 				k_chip->max_flash_prog_size = 1<<10;
 				break;
 
@@ -1932,7 +2055,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
 				k_chip->nvm_sector_size = 4<<10;
 				k_chip->max_flash_prog_size = 1<<10;
 				num_blocks = 2;
-				k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
+				k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
 				break;
 
 			case KINETIS_SDID_FAMILYID_K2X | KINETIS_SDID_SUBFAMID_KX6:
@@ -1943,7 +2066,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
 				k_chip->nvm_sector_size = 4<<10;
 				k_chip->max_flash_prog_size = 1<<10;
 				num_blocks = 4;
-				k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_K;
+				k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
 				cpu_mhz = 180;
 				break;
 
@@ -1953,7 +2076,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
 				/* K80FN256, K81FN256, K82FN256 */
 				k_chip->pflash_sector_size = 4<<10;
 				num_blocks = 1;
-				k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_K | FS_NO_CMD_BLOCKSTAT;
+				k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_NO_CMD_BLOCKSTAT;
 				cpu_mhz = 150;
 				break;
 
@@ -1962,7 +2085,9 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
 				/* KL81Z128, KL82Z128 */
 				k_chip->pflash_sector_size = 2<<10;
 				num_blocks = 1;
-				k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_L | FS_NO_CMD_BLOCKSTAT;
+				k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_NO_CMD_BLOCKSTAT;
+				k_chip->cache_type = KINETIS_CACHE_L;
+
 				use_nvm_marking = false;
 				snprintf(name, sizeof(name), "MKL8%uZ%%s7",
 					 subfamid);
@@ -1982,7 +2107,9 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
 			k_chip->pflash_sector_size = 1<<10;
 			k_chip->nvm_sector_size = 1<<10;
 			/* autodetect 1 or 2 blocks */
-			k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_L;
+			k_chip->flash_support = FS_PROGRAM_LONGWORD;
+			k_chip->cache_type = KINETIS_CACHE_L;
+			k_chip->watchdog_type = KINETIS_WDOG_COP;
 
 			cpu_mhz = 48;
 			if (subfamid == 3 && (familyid == 1 || familyid == 2))
@@ -1993,12 +2120,14 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
 
 		case KINETIS_SDID_SERIESID_KV:
 			/* KV-series */
+			k_chip->watchdog_type = KINETIS_WDOG_K;
 			switch (k_chip->sim_sdid & (KINETIS_SDID_FAMILYID_MASK | KINETIS_SDID_SUBFAMID_MASK)) {
 			case KINETIS_SDID_FAMILYID_K1X | KINETIS_SDID_SUBFAMID_KX0:
 				/* KV10: FTFA, 1kB sectors */
 				k_chip->pflash_sector_size = 1<<10;
 				num_blocks = 1;
-				k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_L;
+				k_chip->flash_support = FS_PROGRAM_LONGWORD;
+				k_chip->cache_type = KINETIS_CACHE_L;
 				strcpy(name, "MKV10Z%s7");
 				break;
 
@@ -2006,7 +2135,8 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
 				/* KV11: FTFA, 2kB sectors */
 				k_chip->pflash_sector_size = 2<<10;
 				num_blocks = 1;
-				k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_L;
+				k_chip->flash_support = FS_PROGRAM_LONGWORD;
+				k_chip->cache_type = KINETIS_CACHE_L;
 				strcpy(name, "MKV11Z%s7");
 				break;
 
@@ -2016,7 +2146,8 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
 				/* KV31: FTFA, 2kB sectors, 2 blocks */
 				k_chip->pflash_sector_size = 2<<10;
 				/* autodetect 1 or 2 blocks */
-				k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_K;
+				k_chip->flash_support = FS_PROGRAM_LONGWORD;
+				k_chip->cache_type = KINETIS_CACHE_K;
 				break;
 
 			case KINETIS_SDID_FAMILYID_K4X | KINETIS_SDID_SUBFAMID_KX2:
@@ -2025,7 +2156,8 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
 				/* KV4x: FTFA, 4kB sectors */
 				k_chip->pflash_sector_size = 4<<10;
 				num_blocks = 1;
-				k_chip->flash_support = FS_PROGRAM_LONGWORD | FS_INVALIDATE_CACHE_K;
+				k_chip->flash_support = FS_PROGRAM_LONGWORD;
+				k_chip->cache_type = KINETIS_CACHE_K;
 				cpu_mhz = 168;
 				break;
 
@@ -2053,6 +2185,7 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
 
 		case KINETIS_SDID_SERIESID_KE:
 			/* KE1x-series */
+			k_chip->watchdog_type = KINETIS_WDOG32_KE1X;
 			switch (k_chip->sim_sdid &
 				(KINETIS_SDID_FAMILYID_MASK | KINETIS_SDID_SUBFAMID_MASK | KINETIS_SDID_PROJECTID_MASK)) {
 			case KINETIS_SDID_FAMILYID_K1X | KINETIS_SDID_SUBFAMID_KX4 | KINETIS_SDID_PROJECTID_KE1xZ:
@@ -2062,7 +2195,8 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
 				k_chip->nvm_sector_size = 2<<10;
 				k_chip->max_flash_prog_size = 1<<9;
 				num_blocks = 2;
-				k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_L;
+				k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
+				k_chip->cache_type = KINETIS_CACHE_L;
 
 				cpu_mhz = 72;
 				snprintf(name, sizeof(name), "MKE%u%uZ%%s%u",
@@ -2077,7 +2211,8 @@ static int kinetis_probe_chip(struct kinetis_chip *k_chip)
 				k_chip->nvm_sector_size = 2<<10;
 				k_chip->max_flash_prog_size = 1<<10;
 				num_blocks = 2;
-				k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR | FS_INVALIDATE_CACHE_MSCM;
+				k_chip->flash_support = FS_PROGRAM_PHRASE | FS_PROGRAM_SECTOR;
+				k_chip->cache_type = KINETIS_CACHE_MSCM;
 
 				cpu_mhz = 168;
 				snprintf(name, sizeof(name), "MKE%u%uF%%s%u",
diff --git a/tcl/target/klx.cfg b/tcl/target/klx.cfg
index c2de9f7d50b2a6270172dabfe1c67aba74d04718..7dd0404f96bd3cc633fac71c456298c4e2fd8aed 100644
--- a/tcl/target/klx.cfg
+++ b/tcl/target/klx.cfg
@@ -37,7 +37,8 @@ flash bank $_FLASHNAME kinetis 0 0 0 0 $_TARGETNAME
 kinetis create_banks
 
 # Table 5-1. Clock Summary of KL25 Sub-Family Reference Manual
-# specifies up to 1MHz for VLPR mode.
+# specifies up to 1MHz for VLPR mode and up to 24MHz for run mode;
+# Table 17 of Sub-Family Data Sheet rev4 lists 25MHz as the maximum frequency.
 adapter_khz 1000
 
 reset_config srst_nogate
@@ -53,10 +54,9 @@ if {![using_hla]} {
    cortex_m reset_config sysresetreq
 }
 
-# Table 5-1. Clock Summary of KL25 Sub-Family Reference Manual
-# specifies up to 24MHz for run mode; Table 17 of Sub-Family Data
-# Sheet rev4 lists 25MHz as the maximum frequency.
-# Uncoment only if VLPR mode is not used
-#$_TARGETNAME configure -event reset-init {
-#   adapter_khz 24000
-#}
+# Disable watchdog not to disturb OpenOCD algorithms running on MCU
+# (e.g. armv7m_checksum_memory() in verify_image)
+# Flash driver also disables watchdog before FTFA flash programming.
+$_TARGETNAME configure -event reset-init {
+   kinetis disable_wdog
+}
diff --git a/tcl/target/kx.cfg b/tcl/target/kx.cfg
index cf777135c6614454b452ddc2de971f99f63ff153..7b0351706a9420d3cbf63f5eed40719aeed6e5ed 100644
--- a/tcl/target/kx.cfg
+++ b/tcl/target/kx.cfg
@@ -54,3 +54,11 @@ if {![using_hla]} {
    # perform a soft reset
    cortex_m reset_config sysresetreq
 }
+
+# Disable watchdog not to disturb OpenOCD algorithms running on MCU
+# (e.g. armv7m_checksum_memory() in verify_image)
+# Flash driver also disables watchdog before FTFA flash programming.
+$_TARGETNAME configure -event reset-init {
+   kinetis disable_wdog
+}
+