diff options
author | Robin Gong <yibin.gong@nxp.com> | 2017-11-14 17:03:02 +0800 |
---|---|---|
committer | Leonard Crestez <leonard.crestez@nxp.com> | 2018-08-24 12:41:33 +0300 |
commit | 0d9386b96539844e4b0fdf71fa89b48651bdd25d (patch) | |
tree | 630d5f32b94cae2b0d5d789b531cc9bca546401c /drivers/watchdog | |
parent | eef1db8ee279a487f3ec3a2f61bbee08741edfb9 (diff) |
MLK-16891: watchdog: imx8_wdt: add pre_timeout notification
Add pre_timeout set and notification for i.mx8qm/qxp.
BuildInfo:
- SCFW 36ff24f3, IMX-MKIMAGE 05d3d4a7, ATF 93dd1cc
- U-Boot 2017.03-00684-g28c5243
Signed-off-by: Robin Gong <yibin.gong@nxp.com>
Reviewed-by: Anson Huang <Anson.Huang@nxp.com>
Diffstat (limited to 'drivers/watchdog')
-rw-r--r-- | drivers/watchdog/imx8_wdt.c | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/drivers/watchdog/imx8_wdt.c b/drivers/watchdog/imx8_wdt.c index 108337736974..c78eb0030c85 100644 --- a/drivers/watchdog/imx8_wdt.c +++ b/drivers/watchdog/imx8_wdt.c @@ -16,6 +16,8 @@ #include <linux/reboot.h> #include <linux/watchdog.h> #include <soc/imx/fsl_sip.h> +#include <soc/imx8/sc/sci.h> +#include <soc/imx8/sc/svc/irq/api.h> #define DEFAULT_TIMEOUT 10 /* @@ -27,6 +29,19 @@ static struct watchdog_device imx8_wdd; +static int imx8_wdt_notify(struct notifier_block *nb, + unsigned long event, void *group) +{ + /* ignore other irqs */ + if (!(event & SC_IRQ_WDOG && + (*(sc_irq_group_t *)group == SC_IRQ_GROUP_WDOG))) + return 0; + + watchdog_notify_pretimeout(&imx8_wdd); + + return 0; +} + static int imx8_wdt_ping(struct watchdog_device *wdog) { struct arm_smccc_res res; @@ -73,18 +88,35 @@ static int imx8_wdt_set_timeout(struct watchdog_device *wdog, return res.a0; } +static int imx8_wdt_set_pretimeout(struct watchdog_device *wdog, + unsigned int new_pretimeout) +{ + struct arm_smccc_res res; + + arm_smccc_smc(FSL_SIP_SRTC, FSL_SIP_SRTC_SET_PRETIME_WDOG, + new_pretimeout * 1000, 0, 0, 0, 0, 0, + &res); + + return res.a0; +} + static const struct watchdog_ops imx8_wdt_ops = { .owner = THIS_MODULE, .start = imx8_wdt_start, .stop = imx8_wdt_stop, .ping = imx8_wdt_ping, .set_timeout = imx8_wdt_set_timeout, + .set_pretimeout = imx8_wdt_set_pretimeout, }; static const struct watchdog_info imx8_wdt_info = { .identity = "i.MX8 watchdog timer", .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | - WDIOF_MAGICCLOSE, + WDIOF_MAGICCLOSE | WDIOF_PRETIMEOUT, +}; + +static struct notifier_block imx8_wdt_notifier = { + .notifier_call = imx8_wdt_notify, }; static int imx8_wdt_probe(struct platform_device *pdev) @@ -114,7 +146,7 @@ static int imx8_wdt_probe(struct platform_device *pdev) return err; } - return 0; + return register_scu_notifier(&imx8_wdt_notifier); } static int imx8_wdt_remove(struct platform_device *pdev) |