1 /* 2 * Hisilicon SoC reset code 3 * 4 * Copyright (c) 2014 Hisilicon Ltd. 5 * Copyright (c) 2014 Linaro Ltd. 6 * 7 * Author: Haojian Zhuang <haojian.zhuang@linaro.org> 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 as 11 * published by the Free Software Foundation. 12 */ 13 14 #include <linux/delay.h> 15 #include <linux/io.h> 16 #include <linux/module.h> 17 #include <linux/of_address.h> 18 #include <linux/platform_device.h> 19 #include <linux/reboot.h> 20 21 #include <asm/proc-fns.h> 22 #include <asm/system_misc.h> 23 24 static void __iomem *base; 25 static u32 reboot_offset; 26 27 static void hisi_restart(enum reboot_mode mode, const char *cmd) 28 { 29 writel_relaxed(0xdeadbeef, base + reboot_offset); 30 31 while (1) 32 cpu_do_idle(); 33 } 34 35 static int hisi_reboot_probe(struct platform_device *pdev) 36 { 37 struct device_node *np = pdev->dev.of_node; 38 39 base = of_iomap(np, 0); 40 if (!base) { 41 WARN(1, "failed to map base address"); 42 return -ENODEV; 43 } 44 45 if (of_property_read_u32(np, "reboot-offset", &reboot_offset) < 0) { 46 pr_err("failed to find reboot-offset property\n"); 47 return -EINVAL; 48 } 49 50 arm_pm_restart = hisi_restart; 51 52 return 0; 53 } 54 55 static struct of_device_id hisi_reboot_of_match[] = { 56 { .compatible = "hisilicon,sysctrl" }, 57 {} 58 }; 59 60 static struct platform_driver hisi_reboot_driver = { 61 .probe = hisi_reboot_probe, 62 .driver = { 63 .name = "hisi-reboot", 64 .of_match_table = hisi_reboot_of_match, 65 }, 66 }; 67 module_platform_driver(hisi_reboot_driver); 68