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
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;
.auto_probe = sam3_auto_probe,
.erase_check = sam3_erase_check,
.protect_check = sam3_protect_check,
+ .free_driver_priv = sam3_free_driver_priv,
};
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;
.auto_probe = sam4_auto_probe,
.erase_check = default_flash_blank_check,
.protect_check = sam4_protect_check,
+ .free_driver_priv = sam4_free_driver_priv,
};
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)
{
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] )",
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;
}
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");
.auto_probe = sam4l_probe,
.erase_check = default_flash_blank_check,
.protect_check = sam4l_protect_check,
+ .free_driver_priv = default_flash_free_driver_priv,
};
bool probed;
struct target *target;
- struct samd_info *next;
};
-static struct samd_info *samd_chips;
/**
* Gives the family structure to specific device id.
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] )",
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;
}
.auto_probe = samd_probe,
.erase_check = default_flash_blank_check,
.protect_check = samd_protect_check,
+ .free_driver_priv = default_flash_free_driver_priv,
};