summaryrefslogtreecommitdiff
path: root/arch/powerpc/sysdev/fsl_soc.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/sysdev/fsl_soc.c')
-rw-r--r--arch/powerpc/sysdev/fsl_soc.c33
1 files changed, 20 insertions, 13 deletions
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index a09ca704de58..d93056eedcb0 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -29,6 +29,7 @@
#include <linux/fsl_devices.h>
#include <linux/fs_enet_pd.h>
#include <linux/fs_uart_pd.h>
+#include <linux/reboot.h>
#include <linux/atomic.h>
#include <asm/io.h>
@@ -180,23 +181,38 @@ EXPORT_SYMBOL(get_baudrate);
#if defined(CONFIG_FSL_SOC_BOOKE) || defined(CONFIG_PPC_86xx)
static __be32 __iomem *rstcr;
+static int fsl_rstcr_restart(struct notifier_block *this,
+ unsigned long mode, void *cmd)
+{
+ local_irq_disable();
+ /* set reset control register */
+ out_be32(rstcr, 0x2); /* HRESET_REQ */
+
+ return NOTIFY_DONE;
+}
+
static int __init setup_rstcr(void)
{
struct device_node *np;
+ static struct notifier_block restart_handler = {
+ .notifier_call = fsl_rstcr_restart,
+ .priority = 128,
+ };
+
for_each_node_by_name(np, "global-utilities") {
if ((of_get_property(np, "fsl,has-rstcr", NULL))) {
rstcr = of_iomap(np, 0) + 0xb0;
- if (!rstcr)
+ if (!rstcr) {
printk (KERN_ERR "Error: reset control "
"register not mapped!\n");
+ } else {
+ register_restart_handler(&restart_handler);
+ }
break;
}
}
- if (!rstcr && ppc_md.restart == fsl_rstcr_restart)
- printk(KERN_ERR "No RSTCR register, warm reboot won't work\n");
-
of_node_put(np);
return 0;
@@ -204,15 +220,6 @@ static int __init setup_rstcr(void)
arch_initcall(setup_rstcr);
-void __noreturn fsl_rstcr_restart(char *cmd)
-{
- local_irq_disable();
- if (rstcr)
- /* set reset control register */
- out_be32(rstcr, 0x2); /* HRESET_REQ */
-
- while (1) ;
-}
#endif
#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)