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 <vanekt@fbl.cz> Reviewed-on: http://openocd.zylin.com/4416 Tested-by: jenkins
This commit is contained in:
parent
66d924f787
commit
a9fb0d07f0
|
@ -3117,6 +3117,22 @@ FLASH_BANK_COMMAND_HANDLER(sam3_flash_bank_command)
|
||||||
return ERROR_OK;
|
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)
|
static int sam3_GetDetails(struct sam3_bank_private *pPrivate)
|
||||||
{
|
{
|
||||||
const struct sam3_chip_details *pDetails;
|
const struct sam3_chip_details *pDetails;
|
||||||
|
@ -3771,4 +3787,5 @@ struct flash_driver at91sam3_flash = {
|
||||||
.auto_probe = sam3_auto_probe,
|
.auto_probe = sam3_auto_probe,
|
||||||
.erase_check = sam3_erase_check,
|
.erase_check = sam3_erase_check,
|
||||||
.protect_check = sam3_protect_check,
|
.protect_check = sam3_protect_check,
|
||||||
|
.free_driver_priv = sam3_free_driver_priv,
|
||||||
};
|
};
|
||||||
|
|
|
@ -2514,6 +2514,22 @@ FLASH_BANK_COMMAND_HANDLER(sam4_flash_bank_command)
|
||||||
return ERROR_OK;
|
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)
|
static int sam4_GetDetails(struct sam4_bank_private *pPrivate)
|
||||||
{
|
{
|
||||||
const struct sam4_chip_details *pDetails;
|
const struct sam4_chip_details *pDetails;
|
||||||
|
@ -3194,4 +3210,5 @@ struct flash_driver at91sam4_flash = {
|
||||||
.auto_probe = sam4_auto_probe,
|
.auto_probe = sam4_auto_probe,
|
||||||
.erase_check = default_flash_blank_check,
|
.erase_check = default_flash_blank_check,
|
||||||
.protect_check = sam4_protect_check,
|
.protect_check = sam4_protect_check,
|
||||||
|
.free_driver_priv = sam4_free_driver_priv,
|
||||||
};
|
};
|
||||||
|
|
|
@ -129,10 +129,8 @@ struct sam4l_info {
|
||||||
|
|
||||||
bool probed;
|
bool probed;
|
||||||
struct target *target;
|
struct target *target;
|
||||||
struct sam4l_info *next;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct sam4l_info *sam4l_chips;
|
|
||||||
|
|
||||||
static int sam4l_flash_wait_until_ready(struct target *target)
|
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)
|
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) {
|
if (bank->base != SAM4L_FLASH) {
|
||||||
LOG_ERROR("Address 0x%08" PRIx32 " invalid bank address (try 0x%08" PRIx32
|
LOG_ERROR("Address 0x%08" PRIx32 " invalid bank address (try 0x%08" PRIx32
|
||||||
"[at91sam4l series] )",
|
"[at91sam4l series] )",
|
||||||
|
@ -235,6 +209,18 @@ FLASH_BANK_COMMAND_HANDLER(sam4l_flash_bank_command)
|
||||||
return ERROR_FAIL;
|
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;
|
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)
|
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) {
|
if (bank->target->state != TARGET_HALTED) {
|
||||||
LOG_ERROR("Target not halted");
|
LOG_ERROR("Target not halted");
|
||||||
|
@ -709,4 +695,5 @@ struct flash_driver at91sam4l_flash = {
|
||||||
.auto_probe = sam4l_probe,
|
.auto_probe = sam4l_probe,
|
||||||
.erase_check = default_flash_blank_check,
|
.erase_check = default_flash_blank_check,
|
||||||
.protect_check = sam4l_protect_check,
|
.protect_check = sam4l_protect_check,
|
||||||
|
.free_driver_priv = default_flash_free_driver_priv,
|
||||||
};
|
};
|
||||||
|
|
|
@ -304,10 +304,8 @@ struct samd_info {
|
||||||
|
|
||||||
bool probed;
|
bool probed;
|
||||||
struct target *target;
|
struct target *target;
|
||||||
struct samd_info *next;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct samd_info *samd_chips;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gives the family structure to specific device id.
|
* Gives the family structure to specific device id.
|
||||||
|
@ -876,30 +874,6 @@ free_pb:
|
||||||
|
|
||||||
FLASH_BANK_COMMAND_HANDLER(samd_flash_bank_command)
|
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) {
|
if (bank->base != SAMD_FLASH) {
|
||||||
LOG_ERROR("Address 0x%08" PRIx32 " invalid bank address (try 0x%08" PRIx32
|
LOG_ERROR("Address 0x%08" PRIx32 " invalid bank address (try 0x%08" PRIx32
|
||||||
"[at91samd series] )",
|
"[at91samd series] )",
|
||||||
|
@ -907,6 +881,18 @@ FLASH_BANK_COMMAND_HANDLER(samd_flash_bank_command)
|
||||||
return ERROR_FAIL;
|
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;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1281,4 +1267,5 @@ struct flash_driver at91samd_flash = {
|
||||||
.auto_probe = samd_probe,
|
.auto_probe = samd_probe,
|
||||||
.erase_check = default_flash_blank_check,
|
.erase_check = default_flash_blank_check,
|
||||||
.protect_check = samd_protect_check,
|
.protect_check = samd_protect_check,
|
||||||
|
.free_driver_priv = default_flash_free_driver_priv,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue