#include <asm/prom.h>
 #include <asm/mpc52xx.h>
 
+/*
+ * This variable is mapped in mpc52xx_map_wdt() and used in mpc52xx_restart().
+ * Permanent mapping is required because mpc52xx_restart() can be called
+ * from interrupt context while node mapping (which calls ioremap())
+ * cannot be used at such point.
+ */
+static volatile struct mpc52xx_gpt *mpc52xx_wdt = NULL;
 
 static void __iomem *
 mpc52xx_map_node(struct device_node *ofn)
                        "Error while probing of_platform bus\n");
 }
 
+void __init
+mpc52xx_map_wdt(void)
+{
+       const void *has_wdt;
+       struct device_node *np;
+
+       /* mpc52xx_wdt is mapped here and used in mpc52xx_restart,
+        * possibly from a interrupt context. wdt is only implement
+        * on a gpt0, so check has-wdt property before mapping.
+        */
+       for_each_compatible_node(np, NULL, "fsl,mpc5200-gpt") {
+               has_wdt = of_get_property(np, "fsl,has-wdt", NULL);
+               if (has_wdt) {
+                       mpc52xx_wdt = mpc52xx_map_node(np);
+                       return;
+               }
+       }
+       for_each_compatible_node(np, NULL, "mpc5200-gpt") {
+               has_wdt = of_get_property(np, "has-wdt", NULL);
+               if (has_wdt) {
+                       mpc52xx_wdt = mpc52xx_map_node(np);
+                       return;
+               }
+       }
+}
+
+void
+mpc52xx_restart(char *cmd)
+{
+       local_irq_disable();
+
+       /* Turn on the watchdog and wait for it to expire.
+        * It effectively does a reset. */
+       if (mpc52xx_wdt) {
+               out_be32(&mpc52xx_wdt->mode, 0x00000000);
+               out_be32(&mpc52xx_wdt->count, 0x000000ff);
+               out_be32(&mpc52xx_wdt->mode, 0x00009004);
+       } else
+               printk("mpc52xx_restart: Can't access wdt. "
+                       "Restart impossible, system halted.\n");
+
+       while (1);
+}