]>
Commit | Line | Data |
---|---|---|
f9917454 SG |
1 | /* |
2 | * Copyright (C) 2015 Google, Inc | |
3 | * Written by Simon Glass <sjg@chromium.org> | |
4 | * | |
5 | * SPDX-License-Identifier: GPL-2.0+ | |
6 | */ | |
7 | ||
8 | #include <common.h> | |
11636258 | 9 | #include <sysreset.h> |
f9917454 SG |
10 | #include <dm.h> |
11 | #include <errno.h> | |
12 | #include <regmap.h> | |
13 | #include <dm/device-internal.h> | |
14 | #include <dm/lists.h> | |
15 | #include <dm/root.h> | |
16 | #include <linux/err.h> | |
17 | ||
11636258 | 18 | int sysreset_request(struct udevice *dev, enum sysreset_t type) |
f9917454 | 19 | { |
11636258 | 20 | struct sysreset_ops *ops = sysreset_get_ops(dev); |
f9917454 SG |
21 | |
22 | if (!ops->request) | |
23 | return -ENOSYS; | |
24 | ||
25 | return ops->request(dev, type); | |
26 | } | |
27 | ||
11636258 | 28 | int sysreset_walk(enum sysreset_t type) |
f9917454 SG |
29 | { |
30 | struct udevice *dev; | |
1704d083 | 31 | int ret = -ENOSYS; |
f9917454 | 32 | |
11636258 SW |
33 | while (ret != -EINPROGRESS && type < SYSRESET_COUNT) { |
34 | for (uclass_first_device(UCLASS_SYSRESET, &dev); | |
1704d083 SG |
35 | dev; |
36 | uclass_next_device(&dev)) { | |
11636258 | 37 | ret = sysreset_request(dev, type); |
f9917454 SG |
38 | if (ret == -EINPROGRESS) |
39 | break; | |
40 | } | |
1704d083 | 41 | type++; |
f9917454 SG |
42 | } |
43 | ||
1704d083 SG |
44 | return ret; |
45 | } | |
46 | ||
11636258 | 47 | void sysreset_walk_halt(enum sysreset_t type) |
1704d083 SG |
48 | { |
49 | int ret; | |
50 | ||
11636258 | 51 | ret = sysreset_walk(type); |
1704d083 | 52 | |
f9917454 | 53 | /* Wait for the reset to take effect */ |
1704d083 SG |
54 | if (ret == -EINPROGRESS) |
55 | mdelay(100); | |
f9917454 SG |
56 | |
57 | /* Still no reset? Give up */ | |
5c086215 | 58 | debug("System reset not supported on this platform\n"); |
f9917454 SG |
59 | hang(); |
60 | } | |
61 | ||
62 | /** | |
11636258 | 63 | * reset_cpu() - calls sysreset_walk(SYSRESET_WARM) |
f9917454 SG |
64 | */ |
65 | void reset_cpu(ulong addr) | |
66 | { | |
11636258 | 67 | sysreset_walk_halt(SYSRESET_WARM); |
1704d083 SG |
68 | } |
69 | ||
70 | ||
71 | int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | |
72 | { | |
11636258 | 73 | sysreset_walk_halt(SYSRESET_WARM); |
1704d083 SG |
74 | |
75 | return 0; | |
f9917454 SG |
76 | } |
77 | ||
11636258 SW |
78 | UCLASS_DRIVER(sysreset) = { |
79 | .id = UCLASS_SYSRESET, | |
80 | .name = "sysreset", | |
f9917454 | 81 | }; |