]>
Commit | Line | Data |
---|---|---|
f9917454 SG |
1 | /* |
2 | * Copyright (C) 2015 Google, Inc | |
3 | * Written by Simon Glass <[email protected]> | |
4 | * | |
5 | * SPDX-License-Identifier: GPL-2.0+ | |
6 | */ | |
7 | ||
8 | #include <common.h> | |
9 | #include <reset.h> | |
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 | ||
18 | int reset_request(struct udevice *dev, enum reset_t type) | |
19 | { | |
20 | struct reset_ops *ops = reset_get_ops(dev); | |
21 | ||
22 | if (!ops->request) | |
23 | return -ENOSYS; | |
24 | ||
25 | return ops->request(dev, type); | |
26 | } | |
27 | ||
1704d083 | 28 | int reset_walk(enum reset_t type) |
f9917454 SG |
29 | { |
30 | struct udevice *dev; | |
1704d083 | 31 | int ret = -ENOSYS; |
f9917454 SG |
32 | |
33 | while (ret != -EINPROGRESS && type < RESET_COUNT) { | |
34 | for (uclass_first_device(UCLASS_RESET, &dev); | |
1704d083 SG |
35 | dev; |
36 | uclass_next_device(&dev)) { | |
f9917454 SG |
37 | ret = reset_request(dev, type); |
38 | if (ret == -EINPROGRESS) | |
39 | break; | |
40 | } | |
1704d083 | 41 | type++; |
f9917454 SG |
42 | } |
43 | ||
1704d083 SG |
44 | return ret; |
45 | } | |
46 | ||
47 | void reset_walk_halt(enum reset_t type) | |
48 | { | |
49 | int ret; | |
50 | ||
51 | ret = reset_walk(type); | |
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 */ | |
58 | printf("Reset not supported on this platform\n"); | |
59 | hang(); | |
60 | } | |
61 | ||
62 | /** | |
63 | * reset_cpu() - calls reset_walk(RESET_WARM) | |
64 | */ | |
65 | void reset_cpu(ulong addr) | |
66 | { | |
1704d083 SG |
67 | reset_walk_halt(RESET_WARM); |
68 | } | |
69 | ||
70 | ||
71 | int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | |
72 | { | |
73 | reset_walk_halt(RESET_WARM); | |
74 | ||
75 | return 0; | |
f9917454 SG |
76 | } |
77 | ||
78 | UCLASS_DRIVER(reset) = { | |
79 | .id = UCLASS_RESET, | |
80 | .name = "reset", | |
81 | }; |