]> git.sur5r.net Git - openocd/commitdiff
flash/nor/at91sam: implement flash bank deallocation for SAM series
authorTomas Vanek <vanekt@fbl.cz>
Thu, 15 Feb 2018 09:18:37 +0000 (10:18 +0100)
committerTomas Vanek <vanekt@fbl.cz>
Tue, 10 Apr 2018 05:19:01 +0000 (06:19 +0100)
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 <vanekt@fbl.cz>
Reviewed-on: http://openocd.zylin.com/4416
Tested-by: jenkins
src/flash/nor/at91sam3.c
src/flash/nor/at91sam4.c
src/flash/nor/at91sam4l.c
src/flash/nor/at91samd.c

index 1536378df21bd01b10db66eed94251f13d9e2691..d80b6fe6e8d78309d27d0ae4f940f762327605d1 100644 (file)
@@ -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,
 };
index d101c9b4cb7e702acd0e607a8780199e085ec8d1..04752169fbee0b0ed0bec362b06658e1a37d13bc 100644 (file)
@@ -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,
 };
index 0a605d5d77647e6a49f2885717fd4a6d7c20ea22..794ccbb01612b8b5dbd1975764a2fe610f5133f2 100644 (file)
@@ -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,
 };
index 64716d96ffc6f16d544683b531897ac4613c4b4b..8553ee8f9a230aa80a25619c8abc7a6e0683f7ee 100644 (file)
@@ -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,
 };