MLK-15083 watchdog: imx2_wdt: fallback to timeout reset if explicit reset fails
If explicit reset fails fallback using the watchdog timeout. We already have set the timeout counter to 0, but we might need to ping the watchdog to load the new timeout, if a previous watchdog timeout value has already been set. We also decrease the time we spend waiting, to give a chance to log that the explicit reset failed and that we fallback to watchdog timeout reset. Signed-off-by: Octavian Purdila <octavian.purdila@nxp.com> [fabio: Resolved conflict with 4.9.84] Signed-off-by: Fabio Estevam <festevam@gmail.com>
This commit is contained in:
parent
20ebb9fb81
commit
0e674a64b8
|
@ -93,6 +93,26 @@ static const struct watchdog_info imx2_wdt_pretimeout_info = {
|
|||
WDIOF_PRETIMEOUT,
|
||||
};
|
||||
|
||||
static int imx2_wdt_ping(struct watchdog_device *wdog)
|
||||
{
|
||||
struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
|
||||
|
||||
regmap_write(wdev->regmap, IMX2_WDT_WSR, IMX2_WDT_SEQ1);
|
||||
regmap_write(wdev->regmap, IMX2_WDT_WSR, IMX2_WDT_SEQ2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static inline bool imx2_wdt_is_running(struct imx2_wdt_device *wdev)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
regmap_read(wdev->regmap, IMX2_WDT_WCR, &val);
|
||||
|
||||
return val & IMX2_WDT_WCR_WDE;
|
||||
}
|
||||
|
||||
|
||||
static int imx2_wdt_restart(struct watchdog_device *wdog, unsigned long action,
|
||||
void *data)
|
||||
{
|
||||
|
@ -108,6 +128,9 @@ static int imx2_wdt_restart(struct watchdog_device *wdog, unsigned long action,
|
|||
/* Assert SRS signal */
|
||||
regmap_write(wdev->regmap, IMX2_WDT_WCR, wcr_enable);
|
||||
|
||||
if (imx2_wdt_is_running(wdev))
|
||||
imx2_wdt_ping(wdog);
|
||||
|
||||
/*
|
||||
* Due to imx6q errata ERR004346 (WDOG: WDOG SRS bit requires to be
|
||||
* written twice), we add another two writes to ensure there must be at
|
||||
|
@ -119,7 +142,9 @@ static int imx2_wdt_restart(struct watchdog_device *wdog, unsigned long action,
|
|||
regmap_write(wdev->regmap, IMX2_WDT_WCR, wcr_enable);
|
||||
|
||||
/* wait for reset to assert... */
|
||||
mdelay(500);
|
||||
mdelay(100);
|
||||
dev_err(wdog->parent, "failed to assert %s reset, trying with timeout\n",
|
||||
wdev->ext_reset ? "external" : "internal");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -153,24 +178,6 @@ static inline void imx2_wdt_setup(struct watchdog_device *wdog)
|
|||
regmap_write(wdev->regmap, IMX2_WDT_WCR, val);
|
||||
}
|
||||
|
||||
static inline bool imx2_wdt_is_running(struct imx2_wdt_device *wdev)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
regmap_read(wdev->regmap, IMX2_WDT_WCR, &val);
|
||||
|
||||
return val & IMX2_WDT_WCR_WDE;
|
||||
}
|
||||
|
||||
static int imx2_wdt_ping(struct watchdog_device *wdog)
|
||||
{
|
||||
struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
|
||||
|
||||
regmap_write(wdev->regmap, IMX2_WDT_WSR, IMX2_WDT_SEQ1);
|
||||
regmap_write(wdev->regmap, IMX2_WDT_WSR, IMX2_WDT_SEQ2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __imx2_wdt_set_timeout(struct watchdog_device *wdog,
|
||||
unsigned int new_timeout)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue