summaryrefslogtreecommitdiff
path: root/drivers/watchdog
diff options
context:
space:
mode:
authorRobin Gong <yibin.gong@nxp.com>2017-11-14 17:03:02 +0800
committerLeonard Crestez <leonard.crestez@nxp.com>2018-08-24 12:41:33 +0300
commit0d9386b96539844e4b0fdf71fa89b48651bdd25d (patch)
tree630d5f32b94cae2b0d5d789b531cc9bca546401c /drivers/watchdog
parenteef1db8ee279a487f3ec3a2f61bbee08741edfb9 (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.c36
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)