1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Renesas R-Mobile Reset Driver 4 * 5 * Copyright (C) 2014 Glider bvba 6 */ 7 8 #include <linux/io.h> 9 #include <linux/module.h> 10 #include <linux/notifier.h> 11 #include <linux/of_address.h> 12 #include <linux/platform_device.h> 13 #include <linux/printk.h> 14 #include <linux/reboot.h> 15 16 /* SYSC Register Bank 2 */ 17 #define RESCNT2 0x20 /* Reset Control Register 2 */ 18 19 /* Reset Control Register 2 */ 20 #define RESCNT2_PRES 0x80000000 /* Soft power-on reset */ 21 22 static int rmobile_reset_handler(struct sys_off_data *data) 23 { 24 void __iomem *sysc_base2 = (void __iomem *)data->cb_data; 25 26 /* Let's assume we have acquired the HPB semaphore */ 27 writel(RESCNT2_PRES, sysc_base2 + RESCNT2); 28 29 return NOTIFY_DONE; 30 } 31 32 static int rmobile_reset_probe(struct platform_device *pdev) 33 { 34 void __iomem *sysc_base2; 35 int error; 36 37 sysc_base2 = devm_platform_ioremap_resource(pdev, 1); 38 if (IS_ERR(sysc_base2)) 39 return PTR_ERR(sysc_base2); 40 41 error = devm_register_sys_off_handler(&pdev->dev, 42 SYS_OFF_MODE_RESTART, 43 SYS_OFF_PRIO_HIGH, 44 rmobile_reset_handler, 45 (__force void *)sysc_base2); 46 if (error) { 47 dev_err(&pdev->dev, 48 "cannot register restart handler (err=%d)\n", error); 49 return error; 50 } 51 52 return 0; 53 } 54 55 static const struct of_device_id rmobile_reset_of_match[] = { 56 { .compatible = "renesas,sysc-rmobile", }, 57 { /* sentinel */ } 58 }; 59 MODULE_DEVICE_TABLE(of, rmobile_reset_of_match); 60 61 static struct platform_driver rmobile_reset_driver = { 62 .probe = rmobile_reset_probe, 63 .driver = { 64 .name = "rmobile_reset", 65 .of_match_table = rmobile_reset_of_match, 66 }, 67 }; 68 69 module_platform_driver(rmobile_reset_driver); 70 71 MODULE_DESCRIPTION("Renesas R-Mobile Reset Driver"); 72 MODULE_AUTHOR("Geert Uytterhoeven <geert+renesas@glider.be>"); 73 MODULE_LICENSE("GPL v2"); 74