]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
11f4dc15 SG |
2 | /* |
3 | * Copyright (C) 2015 Google, Inc | |
4 | * Written by Simon Glass <[email protected]> | |
11f4dc15 SG |
5 | */ |
6 | ||
7 | #include <common.h> | |
8 | #include <cpu.h> | |
9 | #include <dm.h> | |
166c3984 | 10 | #include <errno.h> |
f7ae49fc | 11 | #include <log.h> |
11f4dc15 SG |
12 | #include <dm/lists.h> |
13 | #include <dm/root.h> | |
4c809aee | 14 | #include <linux/err.h> |
11f4dc15 | 15 | |
57370de3 MS |
16 | int cpu_probe_all(void) |
17 | { | |
18 | struct udevice *cpu; | |
19 | int ret; | |
20 | ||
21 | ret = uclass_first_device(UCLASS_CPU, &cpu); | |
22 | if (ret) { | |
23 | debug("%s: No CPU found (err = %d)\n", __func__, ret); | |
24 | return ret; | |
25 | } | |
26 | ||
27 | while (cpu) { | |
28 | ret = uclass_next_device(&cpu); | |
29 | if (ret) { | |
30 | debug("%s: Error while probing CPU (err = %d)\n", | |
31 | __func__, ret); | |
32 | return ret; | |
33 | } | |
34 | } | |
35 | ||
36 | return 0; | |
37 | } | |
38 | ||
4c809aee PF |
39 | int cpu_is_current(struct udevice *cpu) |
40 | { | |
41 | struct cpu_ops *ops = cpu_get_ops(cpu); | |
42 | ||
43 | if (ops->is_current) { | |
44 | if (ops->is_current(cpu)) | |
45 | return 1; | |
46 | } | |
47 | ||
48 | return -ENOSYS; | |
49 | } | |
50 | ||
51 | struct udevice *cpu_get_current_dev(void) | |
52 | { | |
53 | struct udevice *cpu; | |
54 | int ret; | |
55 | ||
56 | uclass_foreach_dev_probe(UCLASS_CPU, cpu) { | |
57 | if (cpu_is_current(cpu) > 0) | |
58 | return cpu; | |
59 | } | |
60 | ||
61 | /* If can't find current cpu device, use the first dev instead */ | |
62 | ret = uclass_first_device_err(UCLASS_CPU, &cpu); | |
63 | if (ret) { | |
64 | debug("%s: Could not get CPU device (err = %d)\n", | |
65 | __func__, ret); | |
66 | return NULL; | |
67 | } | |
68 | ||
69 | return cpu; | |
70 | } | |
71 | ||
11f4dc15 SG |
72 | int cpu_get_desc(struct udevice *dev, char *buf, int size) |
73 | { | |
74 | struct cpu_ops *ops = cpu_get_ops(dev); | |
75 | ||
76 | if (!ops->get_desc) | |
77 | return -ENOSYS; | |
78 | ||
79 | return ops->get_desc(dev, buf, size); | |
80 | } | |
81 | ||
82 | int cpu_get_info(struct udevice *dev, struct cpu_info *info) | |
83 | { | |
84 | struct cpu_ops *ops = cpu_get_ops(dev); | |
85 | ||
cb5cbfd5 | 86 | if (!ops->get_info) |
11f4dc15 SG |
87 | return -ENOSYS; |
88 | ||
89 | return ops->get_info(dev, info); | |
90 | } | |
91 | ||
780bfdd3 BM |
92 | int cpu_get_count(struct udevice *dev) |
93 | { | |
94 | struct cpu_ops *ops = cpu_get_ops(dev); | |
95 | ||
96 | if (!ops->get_count) | |
97 | return -ENOSYS; | |
98 | ||
99 | return ops->get_count(dev); | |
100 | } | |
101 | ||
94eaa79c AG |
102 | int cpu_get_vendor(struct udevice *dev, char *buf, int size) |
103 | { | |
104 | struct cpu_ops *ops = cpu_get_ops(dev); | |
105 | ||
106 | if (!ops->get_vendor) | |
107 | return -ENOSYS; | |
108 | ||
109 | return ops->get_vendor(dev, buf, size); | |
110 | } | |
111 | ||
11f4dc15 SG |
112 | U_BOOT_DRIVER(cpu_bus) = { |
113 | .name = "cpu_bus", | |
114 | .id = UCLASS_SIMPLE_BUS, | |
115 | .per_child_platdata_auto_alloc_size = sizeof(struct cpu_platdata), | |
116 | }; | |
117 | ||
118 | static int uclass_cpu_init(struct uclass *uc) | |
119 | { | |
120 | struct udevice *dev; | |
45a26867 | 121 | ofnode node; |
11f4dc15 SG |
122 | int ret; |
123 | ||
45a26867 SG |
124 | node = ofnode_path("/cpus"); |
125 | if (!ofnode_valid(node)) | |
11f4dc15 SG |
126 | return 0; |
127 | ||
128 | ret = device_bind_driver_to_node(dm_root(), "cpu_bus", "cpus", node, | |
129 | &dev); | |
130 | ||
131 | return ret; | |
132 | } | |
133 | ||
134 | UCLASS_DRIVER(cpu) = { | |
135 | .id = UCLASS_CPU, | |
136 | .name = "cpu", | |
137 | .flags = DM_UC_FLAG_SEQ_ALIAS, | |
138 | .init = uclass_cpu_init, | |
139 | }; |