diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 44a3158..f2c2c1a 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -644,6 +644,7 @@ config IMX2_WDT
 config IMX_SC_WDT
 	tristate "IMX SC Watchdog"
 	depends on HAVE_ARM_SMCCC
+	depends on IMX_SCU
 	select WATCHDOG_CORE
 	help
 	  This is the driver for the system controller watchdog
diff --git a/drivers/watchdog/imx_sc_wdt.c b/drivers/watchdog/imx_sc_wdt.c
index 49848b6..f45ed10 100644
--- a/drivers/watchdog/imx_sc_wdt.c
+++ b/drivers/watchdog/imx_sc_wdt.c
@@ -4,6 +4,7 @@
  */
 
 #include <linux/arm-smccc.h>
+#include <linux/firmware/imx/sci.h>
 #include <linux/io.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -33,11 +34,16 @@
 
 #define SC_TIMER_WDOG_ACTION_PARTITION	0
 
+#define SC_IRQ_WDOG			1
+#define SC_IRQ_GROUP_WDOG		1
+
 static bool nowayout = WATCHDOG_NOWAYOUT;
 module_param(nowayout, bool, 0000);
 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
 		 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
 
+struct watchdog_device *imx_sc_wdd;
+
 static int imx_sc_wdt_ping(struct watchdog_device *wdog)
 {
 	struct arm_smccc_res res;
@@ -85,12 +91,42 @@ static int imx_sc_wdt_set_timeout(struct watchdog_device *wdog,
 	return res.a0 ? -EACCES : 0;
 }
 
+static int imx_sc_wdt_set_pretimeout(struct watchdog_device *wdog,
+				     unsigned int pretimeout)
+{
+	struct arm_smccc_res res;
+
+	wdog->pretimeout = pretimeout;
+	arm_smccc_smc(IMX_SIP_TIMER, IMX_SIP_TIMER_SET_PRETIME_WDOG,
+		      pretimeout * 1000, 0, 0, 0, 0, 0, &res);
+
+	return res.a0 ? -EACCES : 0;
+}
+
+static int imx_sc_wdt_notify(struct notifier_block *nb,
+			     unsigned long event, void *group)
+{
+	/* ignore other irqs */
+	if (!(event & SC_IRQ_WDOG &&
+		(*(u8 *)group == SC_IRQ_GROUP_WDOG)))
+		return 0;
+
+	watchdog_notify_pretimeout(imx_sc_wdd);
+
+	return 0;
+}
+
+static struct notifier_block imx_sc_wdt_notifier = {
+	.notifier_call = imx_sc_wdt_notify,
+};
+
 static const struct watchdog_ops imx_sc_wdt_ops = {
 	.owner = THIS_MODULE,
 	.start = imx_sc_wdt_start,
 	.stop  = imx_sc_wdt_stop,
 	.ping  = imx_sc_wdt_ping,
 	.set_timeout = imx_sc_wdt_set_timeout,
+	.set_pretimeout = imx_sc_wdt_set_pretimeout,
 };
 
 static const struct watchdog_info imx_sc_wdt_info = {
@@ -102,9 +138,15 @@ static const struct watchdog_info imx_sc_wdt_info = {
 static int imx_sc_wdt_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
-	struct watchdog_device *imx_sc_wdd;
 	int ret;
 
+	/* wait until i.MX SCU IPC ready */
+	ret = imx_scu_irq_group_enable(SC_IRQ_GROUP_WDOG,
+				       SC_IRQ_WDOG,
+				       true);
+	if (ret == -EPROBE_DEFER)
+		return ret;
+
 	imx_sc_wdd = devm_kzalloc(dev, sizeof(*imx_sc_wdd), GFP_KERNEL);
 	if (!imx_sc_wdd)
 		return -ENOMEM;
@@ -117,6 +159,7 @@ static int imx_sc_wdt_probe(struct platform_device *pdev)
 	imx_sc_wdd->max_timeout = MAX_TIMEOUT;
 	imx_sc_wdd->parent = dev;
 	imx_sc_wdd->timeout = DEFAULT_TIMEOUT;
+	imx_sc_wdd->pretimeout = 0;
 
 	watchdog_init_timeout(imx_sc_wdd, 0, dev);
 	watchdog_stop_on_reboot(imx_sc_wdd);
@@ -128,13 +171,26 @@ static int imx_sc_wdt_probe(struct platform_device *pdev)
 		return ret;
 	}
 
+	ret = imx_scu_irq_register_notifier(&imx_sc_wdt_notifier);
+	if (ret)
+		dev_warn(&pdev->dev,
+			 "Failed to register watchdog irq notifier\n");
+
 	return 0;
 }
 
-static int __maybe_unused imx_sc_wdt_suspend(struct device *dev)
+static int imx_sc_wdt_remove(struct platform_device *pdev)
 {
-	struct watchdog_device *imx_sc_wdd = dev_get_drvdata(dev);
+	imx_scu_irq_unregister_notifier(&imx_sc_wdt_notifier);
+	imx_scu_irq_group_enable(SC_IRQ_GROUP_WDOG,
+				 SC_IRQ_WDOG,
+				 false);
 
+	return 0;
+}
+
+static int __maybe_unused imx_sc_wdt_suspend(struct device *dev)
+{
 	if (watchdog_active(imx_sc_wdd))
 		imx_sc_wdt_stop(imx_sc_wdd);
 
@@ -143,8 +199,6 @@ static int __maybe_unused imx_sc_wdt_suspend(struct device *dev)
 
 static int __maybe_unused imx_sc_wdt_resume(struct device *dev)
 {
-	struct watchdog_device *imx_sc_wdd = dev_get_drvdata(dev);
-
 	if (watchdog_active(imx_sc_wdd))
 		imx_sc_wdt_start(imx_sc_wdd);
 
@@ -162,6 +216,7 @@ MODULE_DEVICE_TABLE(of, imx_sc_wdt_dt_ids);
 
 static struct platform_driver imx_sc_wdt_driver = {
 	.probe		= imx_sc_wdt_probe,
+	.remove		= imx_sc_wdt_remove,
 	.driver		= {
 		.name	= "imx-sc-wdt",
 		.of_match_table = imx_sc_wdt_dt_ids,
