nor/flash: Add keep_alive() during flash write handler
[fw/openocd] / src / flash / nor / at91sam3.c
index 9782fd82fd35c70ae7c8a99b169b06ea0e490f85..c9ffa653b314faf10a2ff61df43fe4ee537b9019 100644 (file)
@@ -8,19 +8,17 @@
  *   Copyright (C) 2011 by Olivier Schonken (at91sam3x* support)           *                                          *
  *                     and Jim Norris                                      *
  *   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  *
+ *   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.                          *
+ *   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.,                                       *
- *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.           *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
 ****************************************************************************/
 
 /* Some of the the lower level code was based on code supplied by
 #define  offset_EFC_FSR   8
 #define  offset_EFC_FRR   12
 
-extern struct flash_driver at91sam3_flash;
+extern const struct flash_driver at91sam3_flash;
 
 static float _tomhz(uint32_t freq_hz)
 {
@@ -251,14 +249,14 @@ struct sam3_reg_list {
 
 static struct sam3_chip *all_sam3_chips;
 
-static struct sam3_chip *get_current_sam3(struct command_context *cmd_ctx)
+static struct sam3_chip *get_current_sam3(struct command_invocation *cmd)
 {
        struct target *t;
        static struct sam3_chip *p;
 
-       t = get_current_target(cmd_ctx);
+       t = get_current_target(cmd->ctx);
        if (!t) {
-               command_print(cmd_ctx, "No current target?");
+               command_print(cmd, "No current target?");
                return NULL;
        }
 
@@ -266,7 +264,7 @@ static struct sam3_chip *get_current_sam3(struct command_context *cmd_ctx)
        if (!p) {
                /* this should not happen */
                /* the command is not registered until the chip is created? */
-               command_print(cmd_ctx, "No SAM3 chips exist?");
+               command_print(cmd, "No SAM3 chips exist?");
                return NULL;
        }
 
@@ -275,7 +273,7 @@ static struct sam3_chip *get_current_sam3(struct command_context *cmd_ctx)
                        return p;
                p = p->next;
        }
-       command_print(cmd_ctx, "Cannot find SAM3 chip?");
+       command_print(cmd, "Cannot find SAM3 chip?");
        return NULL;
 }
 
@@ -2177,7 +2175,7 @@ static int EFC_PerformCommand(struct sam3_bank_private *pPrivate,
 
        int r;
        uint32_t v;
-       long long ms_now, ms_end;
+       int64_t ms_now, ms_end;
 
        /* default */
        if (status)
@@ -2993,28 +2991,6 @@ static int sam3_GetInfo(struct sam3_chip *pChip)
        return ERROR_OK;
 }
 
-static int sam3_erase_check(struct flash_bank *bank)
-{
-       int x;
-
-       LOG_DEBUG("Here");
-       if (bank->target->state != TARGET_HALTED) {
-               LOG_ERROR("Target not halted");
-               return ERROR_TARGET_NOT_HALTED;
-       }
-       if (0 == bank->num_sectors) {
-               LOG_ERROR("Target: not supported/not probed");
-               return ERROR_FAIL;
-       }
-
-       LOG_INFO("sam3 - supports auto-erase, erase_check ignored");
-       for (x = 0; x < bank->num_sectors; x++)
-               bank->sectors[x].is_erased = 1;
-
-       LOG_DEBUG("Done");
-       return ERROR_OK;
-}
-
 static int sam3_protect_check(struct flash_bank *bank)
 {
        int r;
@@ -3092,7 +3068,6 @@ FLASH_BANK_COMMAND_HANDLER(sam3_flash_bank_command)
                    ((unsigned int)(FLASH_BANK1_BASE_256K_AX)),
                    ((unsigned int)(FLASH_BANK1_BASE_512K_AX)));
                        return ERROR_FAIL;
-                       break;
 
                /* at91sam3s and at91sam3n series only has bank 0*/
                /* at91sam3u and at91sam3ax series has the same address for bank 0*/
@@ -3119,6 +3094,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;
@@ -3546,7 +3537,7 @@ done:
 COMMAND_HANDLER(sam3_handle_info_command)
 {
        struct sam3_chip *pChip;
-       pChip = get_current_sam3(CMD_CTX);
+       pChip = get_current_sam3(CMD);
        if (!pChip)
                return ERROR_OK;
 
@@ -3557,7 +3548,7 @@ COMMAND_HANDLER(sam3_handle_info_command)
        if (pChip->details.bank[0].pBank == NULL) {
                x = 0;
 need_define:
-               command_print(CMD_CTX,
+               command_print(CMD,
                        "Please define bank %d via command: flash bank %s ... ",
                        x,
                        at91sam3_flash.name);
@@ -3606,7 +3597,7 @@ COMMAND_HANDLER(sam3_handle_gpnvm_command)
        int r, who;
        struct sam3_chip *pChip;
 
-       pChip = get_current_sam3(CMD_CTX);
+       pChip = get_current_sam3(CMD);
        if (!pChip)
                return ERROR_OK;
 
@@ -3616,7 +3607,7 @@ COMMAND_HANDLER(sam3_handle_gpnvm_command)
        }
 
        if (pChip->details.bank[0].pBank == NULL) {
-               command_print(CMD_CTX, "Bank0 must be defined first via: flash bank %s ...",
+               command_print(CMD, "Bank0 must be defined first via: flash bank %s ...",
                        at91sam3_flash.name);
                return ERROR_FAIL;
        }
@@ -3629,10 +3620,8 @@ COMMAND_HANDLER(sam3_handle_gpnvm_command)
        switch (CMD_ARGC) {
                default:
                        return ERROR_COMMAND_SYNTAX_ERROR;
-                       break;
                case 0:
                        goto showall;
-                       break;
                case 1:
                        who = -1;
                        break;
@@ -3655,22 +3644,23 @@ showall:
                                r = FLASHD_GetGPNVM(&(pChip->details.bank[0]), x, &v);
                                if (r != ERROR_OK)
                                        break;
-                               command_print(CMD_CTX, "sam3-gpnvm%u: %u", x, v);
+                               command_print(CMD, "sam3-gpnvm%u: %u", x, v);
                        }
                        return r;
                }
                if ((who >= 0) && (((unsigned)(who)) < pChip->details.n_gpnvms)) {
                        r = FLASHD_GetGPNVM(&(pChip->details.bank[0]), who, &v);
-                       command_print(CMD_CTX, "sam3-gpnvm%u: %u", who, v);
+                       if (r == ERROR_OK)
+                               command_print(CMD, "sam3-gpnvm%u: %u", who, v);
                        return r;
                } else {
-                       command_print(CMD_CTX, "sam3-gpnvm invalid GPNVM: %u", who);
+                       command_print(CMD, "sam3-gpnvm invalid GPNVM: %u", who);
                        return ERROR_COMMAND_SYNTAX_ERROR;
                }
        }
 
        if (who == -1) {
-               command_print(CMD_CTX, "Missing GPNVM number");
+               command_print(CMD, "Missing GPNVM number");
                return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
@@ -3680,7 +3670,7 @@ showall:
                 (0 == strcmp("clear", CMD_ARGV[0])))                   /* quietly accept both */
                r = FLASHD_ClrGPNVM(&(pChip->details.bank[0]), who);
        else {
-               command_print(CMD_CTX, "Unknown command: %s", CMD_ARGV[0]);
+               command_print(CMD, "Unknown command: %s", CMD_ARGV[0]);
                r = ERROR_COMMAND_SYNTAX_ERROR;
        }
        return r;
@@ -3690,7 +3680,7 @@ COMMAND_HANDLER(sam3_handle_slowclk_command)
 {
        struct sam3_chip *pChip;
 
-       pChip = get_current_sam3(CMD_CTX);
+       pChip = get_current_sam3(CMD);
        if (!pChip)
                return ERROR_OK;
 
@@ -3705,7 +3695,7 @@ COMMAND_HANDLER(sam3_handle_slowclk_command)
                        COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], v);
                        if (v > 200000) {
                                /* absurd slow clock of 200Khz? */
-                               command_print(CMD_CTX, "Absurd/illegal slow clock freq: %d\n", (int)(v));
+                               command_print(CMD, "Absurd/illegal slow clock freq: %d\n", (int)(v));
                                return ERROR_COMMAND_SYNTAX_ERROR;
                        }
                        pChip->cfg.slow_freq = v;
@@ -3713,11 +3703,10 @@ COMMAND_HANDLER(sam3_handle_slowclk_command)
                }
                default:
                        /* error */
-                       command_print(CMD_CTX, "Too many parameters");
+                       command_print(CMD, "Too many parameters");
                        return ERROR_COMMAND_SYNTAX_ERROR;
-                       break;
        }
-       command_print(CMD_CTX, "Slowclk freq: %d.%03dkhz",
+       command_print(CMD, "Slowclk freq: %d.%03dkhz",
                (int)(pChip->cfg.slow_freq / 1000),
                (int)(pChip->cfg.slow_freq % 1000));
        return ERROR_OK;
@@ -3737,8 +3726,9 @@ static const struct command_registration at91sam3_exec_command_handlers[] = {
                .name = "info",
                .handler = sam3_handle_info_command,
                .mode = COMMAND_EXEC,
-               .help = "Print information about the current at91sam3 chip"
+               .help = "Print information about the current at91sam3 chip "
                        "and its flash configuration.",
+               .usage = "",
        },
        {
                .name = "slowclk",
@@ -3761,7 +3751,7 @@ static const struct command_registration at91sam3_command_handlers[] = {
        COMMAND_REGISTRATION_DONE
 };
 
-struct flash_driver at91sam3_flash = {
+const struct flash_driver at91sam3_flash = {
        .name = "at91sam3",
        .commands = at91sam3_command_handlers,
        .flash_bank_command = sam3_flash_bank_command,
@@ -3771,6 +3761,7 @@ struct flash_driver at91sam3_flash = {
        .read = default_flash_read,
        .probe = sam3_probe,
        .auto_probe = sam3_auto_probe,
-       .erase_check = sam3_erase_check,
+       .erase_check = default_flash_blank_check,
        .protect_check = sam3_protect_check,
+       .free_driver_priv = sam3_free_driver_priv,
 };