On 22:03 Fri 07 Aug     , Prafulla Wadaskar wrote:
> This feature can be used to trigger special command "sysrstcmd" using
> reset key long press event and environment variable "sysrstdelay" is set
> (useful for reset to factory or manufacturing mode execution)
> 
> Kirkwood SoC implements a hardware-based SYSRSTn duration counter.
> When SYSRSTn is asserted low, a SYSRSTn duration counter is running.
> The counter value is stored in the SYSRSTn Length Counter Register
> The counter is based on the 25-MHz reference clock (40ns)
> It is a 29-bit counter, yielding a maximum counting duration of
> 2^29/25 MHz (21.4 seconds). When the counter reach its maximum value,
> it remains at this value until counter reset is triggered by setting
> bit 31 of KW_REG_SYSRST_CNT
> 
> Implementation:
> Upon long reset assertion (> ${sysrstdleay} in secs) sysrstcmd will be
> executed if pre-defined in environment variables.
> This feature will be disabled if "sysrstdelay" variable is unset.
> 
> for-ex.
> setenv sysrst_cmd "echo starting factory reset;
>                  nand erase 0xa0000 0x20000;
>                  echo finish ed sysrst command;"
> will erase particular nand sector if triggered by this event
> 
> Signed-off-by: Prafulla Wadaskar <prafu...@marvell.com>
a readme would be nice
and maybe make it more generic so other soc could also implement it
> ---
> Change log:
> v2: command sysrst_cmd renamed as sysrstcmd
> stsrstdelay variable added instead of hardcoding the value
> 
>  cpu/arm926ejs/kirkwood/cpu.c        |   79 
> +++++++++++++++++++++++++++++++++++
>  include/asm-arm/arch-kirkwood/cpu.h |    2 +
>  2 files changed, 81 insertions(+), 0 deletions(-)
> 
> diff --git a/cpu/arm926ejs/kirkwood/cpu.c b/cpu/arm926ejs/kirkwood/cpu.c
> index 795a739..9a6ee57 100644
> --- a/cpu/arm926ejs/kirkwood/cpu.c
> +++ b/cpu/arm926ejs/kirkwood/cpu.c
> @@ -195,6 +195,82 @@ int kw_config_mpp(u32 mpp0_7, u32 mpp8_15, u32 mpp16_23, 
> u32 mpp24_31,
>       return 0;
>  }
>  
> +/*
> + * SYSRSTn Duration Counter Support
> + *
> + * Kirkwood SoC implements a hardware-based SYSRSTn duration counter.
> + * When SYSRSTn is asserted low, a SYSRSTn duration counter is running.
> + * The SYSRSTn duration counter is useful for implementing a manufacturer
> + * or factory reset. Upon a long reset assertion that is greater than a
> + * pre-configured environment variable value for sysrstdelay,
> + * The counter value is stored in the SYSRSTn Length Counter Register
> + * The counter is based on the 25-MHz reference clock (40ns)
> + * It is a 29-bit counter, yielding a maximum counting duration of
> + * 2^29/25 MHz (21.4 seconds). When the counter reach its maximum value,
> + * it remains at this value until counter reset is triggered by setting
> + * bit 31 of KW_REG_SYSRST_CNT
> + */
> +static void kw_sysrst_action(void)
> +{
> +#ifdef CONFIG_CMD_RUN
> +     char cmd[BUFLEN];
> +     char img[BUFLEN * 2];
> +     char *argv[3];
> +
> +     if (getenv("sysrstcmd") == NULL) {
> +             printf("Error.. %s failed, check sysrstcmd\n",
> +                     __FUNCTION__);
> +             return;
> +     }
> +
> +     printf("Starting %s process...\n", __FUNCTION__);
> +     sprintf(cmd, "run ");
> +     sprintf(img, "sysrstcmd");
> +     argv[0] = cmd;
> +     argv[1] = img;
> +     if ((do_run(NULL, 0, 2, argv)) != 0x0) {
> +             printf("Error.. %s failed\n", __FUNCTION__);
> +     } else {
> +             printf("%s process finished\n", __FUNCTION__);
> +     }

> +#else        /* CONFIG_CMD_RUN */
> +     printf("Error.. %s needs run command support\n", __FUNCTION__);
> +#endif       /* CONFIG_CMD_RUN */
why not replace this by

        char *s = getenv("sysrstcmd");

        if (!s) {
                printf("Error.. %s failed, check sysrstcmd\n",
                        __FUNCTION__);
                return;
        }

        printf("Starting %s process...\n", __FUNCTION__);
#if !defined(CONFIG_SYS_HUSH_PARSER)
        ret = run_command (s, 0);
#else
        ret = parse_string_outer(s, FLAG_PARSE_SEMICOLON
                                  | FLAG_EXIT_FROM_LOOP);
#endif
...
> +}
> +
> +static void kw_sysrst_check(void)
> +{
> +     u32 sysrst_cnt, sysrst_dly;
> +     char *s;
> +
> +     /*
> +      * no action if sysrstdelay environment variable is not defined
> +      */
> +     s = getenv("sysrstdelay");
> +     if (s == NULL)
> +             return;
> +
> +     /* read sysrstdelay value */
> +     sysrst_dly = (u32) simple_strtoul(s, NULL, 10);
> +
> +     /* read SysRst Length counter register (bits 28:0) */
> +     sysrst_cnt = (0x1fffffff & readl(KW_REG_SYSRST_CNT));
> +     printf("H/w Rst hold time: %d.%d secs\n",
> +             sysrst_cnt/SYSRST_CNT_1SEC_VAL,
> +             sysrst_cnt%SYSRST_CNT_1SEC_VAL);
please add space before and after %/ etc..
> +
> +     /* clear the counter for next valid read*/
> +     writel(1 << 31, KW_REG_SYSRST_CNT);
> +
> +     /*
> +      * sysrst_action:
> +      * if H/w Reset key is pressed and hold for time
> +      * more than sysrst_dly in seconds
> +      */
> +     if (sysrst_cnt >= SYSRST_CNT_1SEC_VAL * sysrst_dly)
> +             kw_sysrst_action();
> +}
> +
Best Regards,
J.
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to