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, addr: 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, index: 1); |
38 | if (IS_ERR(ptr: sysc_base2)) |
39 | return PTR_ERR(ptr: sysc_base2); |
40 | |
41 | error = devm_register_sys_off_handler(dev: &pdev->dev, |
42 | mode: SYS_OFF_MODE_RESTART, |
43 | SYS_OFF_PRIO_HIGH, |
44 | callback: rmobile_reset_handler, |
45 | cb_data: (__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 | |