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