From a9fb0d07f07f141f9a1c08c21341b3188b21fbe2 Mon Sep 17 00:00:00 2001 From: Tomas Vanek Date: Thu, 15 Feb 2018 10:18:37 +0100 Subject: [PATCH] flash/nor/at91sam: implement flash bank deallocation for SAM series Microchip (former Atmel) SAM drivers allocate a struct per chip. at91sam3, at91sam34: Deallocate all chip structs from the list at once, on the first bank deallocation. at91samd and at91sam4l drivers do not handle more than one bank. Convert them to simple driver_priv allocation and use default_flash_free_driver_priv(). Change-Id: I49d7200f38a4568c7e12f306c27d1b1b72646736 Signed-off-by: Tomas Vanek Reviewed-on: http://openocd.zylin.com/4416 Tested-by: jenkins --- src/flash/nor/at91sam3.c | 17 ++++++++++++++++ src/flash/nor/at91sam4.c | 17 ++++++++++++++++ src/flash/nor/at91sam4l.c | 41 +++++++++++++-------------------------- src/flash/nor/at91samd.c | 39 +++++++++++++------------------------ 4 files changed, 61 insertions(+), 53 deletions(-) diff --git a/src/flash/nor/at91sam3.c b/src/flash/nor/at91sam3.c index 1536378df2..d80b6fe6e8 100644 --- a/src/flash/nor/at91sam3.c +++ b/src/flash/nor/at91sam3.c @@ -3117,6 +3117,22 @@ FLASH_BANK_COMMAND_HANDLER(sam3_flash_bank_command) return ERROR_OK; } +/** + * Remove all chips from the internal list without distingushing which one + * is owned by this bank. This simplification works only for one shot + * deallocation like current flash_free_all_banks() + */ +void sam3_free_driver_priv(struct flash_bank *bank) +{ + struct sam3_chip *chip = all_sam3_chips; + while (chip) { + struct sam3_chip *next = chip->next; + free(chip); + chip = next; + } + all_sam3_chips = NULL; +} + static int sam3_GetDetails(struct sam3_bank_private *pPrivate) { const struct sam3_chip_details *pDetails; @@ -3771,4 +3787,5 @@ struct flash_driver at91sam3_flash = { .auto_probe = sam3_auto_probe, .erase_check = sam3_erase_check, .protect_check = sam3_protect_check, + .free_driver_priv = sam3_free_driver_priv, }; diff --git a/src/flash/nor/at91sam4.c b/src/flash/nor/at91sam4.c index d101c9b4cb..04752169fb 100644 --- a/src/flash/nor/at91sam4.c +++ b/src/flash/nor/at91sam4.c @@ -2514,6 +2514,22 @@ FLASH_BANK_COMMAND_HANDLER(sam4_flash_bank_command) return ERROR_OK; } +/** + * Remove all chips from the internal list without distingushing which one + * is owned by this bank. This simplification works only for one shot + * deallocation like current flash_free_all_banks() + */ +static void sam4_free_driver_priv(struct flash_bank *bank) +{ + struct sam4_chip *chip = all_sam4_chips; + while (chip) { + struct sam4_chip *next = chip->next; + free(chip); + chip = next; + } + all_sam4_chips = NULL; +} + static int sam4_GetDetails(struct sam4_bank_private *pPrivate) { const struct sam4_chip_details *pDetails; @@ -3194,4 +3210,5 @@ struct flash_driver at91sam4_flash = { .auto_probe = sam4_auto_probe, .erase_check = default_flash_blank_check, .protect_check = sam4_protect_check, + .free_driver_priv = sam4_free_driver_priv, }; diff --git a/src/flash/nor/at91sam4l.c b/src/flash/nor/at91sam4l.c index 0a605d5d77..794ccbb016 100644 --- a/src/flash/nor/at91sam4l.c +++ b/src/flash/nor/at91sam4l.c @@ -129,10 +129,8 @@ struct sam4l_info { bool probed; struct target *target; - struct sam4l_info *next; }; -static struct sam4l_info *sam4l_chips; static int sam4l_flash_wait_until_ready(struct target *target) { @@ -204,30 +202,6 @@ static int sam4l_flash_command(struct target *target, uint8_t cmd, int page) FLASH_BANK_COMMAND_HANDLER(sam4l_flash_bank_command) { - struct sam4l_info *chip = sam4l_chips; - - while (chip) { - if (chip->target == bank->target) - break; - chip = chip->next; - } - - if (!chip) { - /* Create a new chip */ - chip = calloc(1, sizeof(*chip)); - if (!chip) - return ERROR_FAIL; - - chip->target = bank->target; - chip->probed = false; - - bank->driver_priv = chip; - - /* Insert it into the chips list (at head) */ - chip->next = sam4l_chips; - sam4l_chips = chip; - } - if (bank->base != SAM4L_FLASH) { LOG_ERROR("Address 0x%08" PRIx32 " invalid bank address (try 0x%08" PRIx32 "[at91sam4l series] )", @@ -235,6 +209,18 @@ FLASH_BANK_COMMAND_HANDLER(sam4l_flash_bank_command) return ERROR_FAIL; } + struct sam4l_info *chip; + chip = calloc(1, sizeof(*chip)); + if (!chip) { + LOG_ERROR("No memory for flash bank chip info"); + return ERROR_FAIL; + } + + chip->target = bank->target; + chip->probed = false; + + bank->driver_priv = chip; + return ERROR_OK; } @@ -396,7 +382,7 @@ static int sam4l_protect_check(struct flash_bank *bank) static int sam4l_protect(struct flash_bank *bank, int set, int first, int last) { - struct sam4l_info *chip = sam4l_chips; + struct sam4l_info *chip = (struct sam4l_info *)bank->driver_priv; if (bank->target->state != TARGET_HALTED) { LOG_ERROR("Target not halted"); @@ -709,4 +695,5 @@ struct flash_driver at91sam4l_flash = { .auto_probe = sam4l_probe, .erase_check = default_flash_blank_check, .protect_check = sam4l_protect_check, + .free_driver_priv = default_flash_free_driver_priv, }; diff --git a/src/flash/nor/at91samd.c b/src/flash/nor/at91samd.c index 64716d96ff..8553ee8f9a 100644 --- a/src/flash/nor/at91samd.c +++ b/src/flash/nor/at91samd.c @@ -304,10 +304,8 @@ struct samd_info { bool probed; struct target *target; - struct samd_info *next; }; -static struct samd_info *samd_chips; /** * Gives the family structure to specific device id. @@ -876,30 +874,6 @@ free_pb: FLASH_BANK_COMMAND_HANDLER(samd_flash_bank_command) { - struct samd_info *chip = samd_chips; - - while (chip) { - if (chip->target == bank->target) - break; - chip = chip->next; - } - - if (!chip) { - /* Create a new chip */ - chip = calloc(1, sizeof(*chip)); - if (!chip) - return ERROR_FAIL; - - chip->target = bank->target; - chip->probed = false; - - bank->driver_priv = chip; - - /* Insert it into the chips list (at head) */ - chip->next = samd_chips; - samd_chips = chip; - } - if (bank->base != SAMD_FLASH) { LOG_ERROR("Address 0x%08" PRIx32 " invalid bank address (try 0x%08" PRIx32 "[at91samd series] )", @@ -907,6 +881,18 @@ FLASH_BANK_COMMAND_HANDLER(samd_flash_bank_command) return ERROR_FAIL; } + struct samd_info *chip; + chip = calloc(1, sizeof(*chip)); + if (!chip) { + LOG_ERROR("No memory for flash bank chip info"); + return ERROR_FAIL; + } + + chip->target = bank->target; + chip->probed = false; + + bank->driver_priv = chip; + return ERROR_OK; } @@ -1281,4 +1267,5 @@ struct flash_driver at91samd_flash = { .auto_probe = samd_probe, .erase_check = default_flash_blank_check, .protect_check = samd_protect_check, + .free_driver_priv = default_flash_free_driver_priv, }; -- 2.30.2