]> git.sur5r.net Git - u-boot/blob - drivers/sysreset/sysreset_syscon.c
3818faeb462fe7761c20c8b42e2e90f3dad2167c
[u-boot] / drivers / sysreset / sysreset_syscon.c
1 /*
2  * Copyright (C) 2017 Álvaro Fernández Rojas <noltari@gmail.com>
3  *
4  * Derived from linux/drivers/power/reset/syscon-reboot.c:
5  *      Copyright (C) 2013, Applied Micro Circuits Corporation
6  *      Author: Feng Kan <fkan@apm.com>
7  *
8  * SPDX-License-Identifier:     GPL-2.0+
9  */
10
11 #include <common.h>
12 #include <dm.h>
13 #include <errno.h>
14 #include <regmap.h>
15 #include <sysreset.h>
16 #include <syscon.h>
17
18 DECLARE_GLOBAL_DATA_PTR;
19
20 struct syscon_reboot_priv {
21         struct regmap *regmap;
22         unsigned int offset;
23         unsigned int mask;
24 };
25
26 static int syscon_reboot_request(struct udevice *dev, enum sysreset_t type)
27 {
28         struct syscon_reboot_priv *priv = dev_get_priv(dev);
29
30         regmap_write(priv->regmap, priv->offset, priv->mask);
31
32         return -EINPROGRESS;
33 }
34
35 static struct sysreset_ops syscon_reboot_ops = {
36         .request = syscon_reboot_request,
37 };
38
39 int syscon_reboot_probe(struct udevice *dev)
40 {
41         struct udevice *syscon;
42         struct syscon_reboot_priv *priv = dev_get_priv(dev);
43         int err;
44
45         err = uclass_get_device_by_phandle(UCLASS_SYSCON, dev,
46                                            "regmap", &syscon);
47         if (err) {
48                 error("unable to find syscon device\n");
49                 return err;
50         }
51
52         priv->regmap = syscon_get_regmap(syscon);
53         if (!priv->regmap) {
54                 error("unable to find regmap\n");
55                 return -ENODEV;
56         }
57
58         priv->offset = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
59                                        "offset", 0);
60         priv->mask = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
61                                        "mask", 0);
62
63         return 0;
64 }
65
66 static const struct udevice_id syscon_reboot_ids[] = {
67         { .compatible = "syscon-reboot" },
68         { /* sentinel */ }
69 };
70
71 U_BOOT_DRIVER(syscon_reboot) = {
72         .name = "syscon_reboot",
73         .id = UCLASS_SYSRESET,
74         .of_match = syscon_reboot_ids,
75         .probe = syscon_reboot_probe,
76         .priv_auto_alloc_size = sizeof(struct syscon_reboot_priv),
77         .ops = &syscon_reboot_ops,
78 };