blob: 8352e2eb0bc5382663a60b633c137d52a6ac1969 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Simon Glass131a6452015-04-28 20:25:09 -06002/*
3 * Copyright (C) 2015 Google, Inc
4 * Written by Simon Glass <sjg@chromium.org>
Simon Glass131a6452015-04-28 20:25:09 -06005 */
6
7#include <common.h>
8#include <cpu.h>
9#include <dm.h>
Bin Mengb891f782015-06-12 14:52:18 +080010#include <errno.h>
Simon Glass131a6452015-04-28 20:25:09 -060011#include <dm/lists.h>
12#include <dm/root.h>
Peng Fan221763a2020-05-03 21:58:47 +080013#include <linux/err.h>
Simon Glass131a6452015-04-28 20:25:09 -060014
Mario Six0263b432018-08-06 10:23:43 +020015int cpu_probe_all(void)
16{
17 struct udevice *cpu;
18 int ret;
19
20 ret = uclass_first_device(UCLASS_CPU, &cpu);
21 if (ret) {
22 debug("%s: No CPU found (err = %d)\n", __func__, ret);
23 return ret;
24 }
25
26 while (cpu) {
27 ret = uclass_next_device(&cpu);
28 if (ret) {
29 debug("%s: Error while probing CPU (err = %d)\n",
30 __func__, ret);
31 return ret;
32 }
33 }
34
35 return 0;
36}
37
Peng Fan221763a2020-05-03 21:58:47 +080038int cpu_is_current(struct udevice *cpu)
39{
40 struct cpu_ops *ops = cpu_get_ops(cpu);
41
42 if (ops->is_current) {
43 if (ops->is_current(cpu))
44 return 1;
45 }
46
47 return -ENOSYS;
48}
49
50struct udevice *cpu_get_current_dev(void)
51{
52 struct udevice *cpu;
53 int ret;
54
55 uclass_foreach_dev_probe(UCLASS_CPU, cpu) {
56 if (cpu_is_current(cpu) > 0)
57 return cpu;
58 }
59
60 /* If can't find current cpu device, use the first dev instead */
61 ret = uclass_first_device_err(UCLASS_CPU, &cpu);
62 if (ret) {
63 debug("%s: Could not get CPU device (err = %d)\n",
64 __func__, ret);
65 return NULL;
66 }
67
68 return cpu;
69}
70
Simon Glass131a6452015-04-28 20:25:09 -060071int cpu_get_desc(struct udevice *dev, char *buf, int size)
72{
73 struct cpu_ops *ops = cpu_get_ops(dev);
74
75 if (!ops->get_desc)
76 return -ENOSYS;
77
78 return ops->get_desc(dev, buf, size);
79}
80
81int cpu_get_info(struct udevice *dev, struct cpu_info *info)
82{
83 struct cpu_ops *ops = cpu_get_ops(dev);
84
Bin Meng6e02ec82015-06-12 14:52:19 +080085 if (!ops->get_info)
Simon Glass131a6452015-04-28 20:25:09 -060086 return -ENOSYS;
87
88 return ops->get_info(dev, info);
89}
90
Bin Mengd13b0142015-06-17 11:15:34 +080091int cpu_get_count(struct udevice *dev)
92{
93 struct cpu_ops *ops = cpu_get_ops(dev);
94
95 if (!ops->get_count)
96 return -ENOSYS;
97
98 return ops->get_count(dev);
99}
100
Alexander Graf67f66bd2016-08-19 01:23:27 +0200101int cpu_get_vendor(struct udevice *dev, char *buf, int size)
102{
103 struct cpu_ops *ops = cpu_get_ops(dev);
104
105 if (!ops->get_vendor)
106 return -ENOSYS;
107
108 return ops->get_vendor(dev, buf, size);
109}
110
Simon Glass131a6452015-04-28 20:25:09 -0600111U_BOOT_DRIVER(cpu_bus) = {
112 .name = "cpu_bus",
113 .id = UCLASS_SIMPLE_BUS,
114 .per_child_platdata_auto_alloc_size = sizeof(struct cpu_platdata),
115};
116
117static int uclass_cpu_init(struct uclass *uc)
118{
119 struct udevice *dev;
Simon Glasse6dd8da2017-05-18 20:09:07 -0600120 ofnode node;
Simon Glass131a6452015-04-28 20:25:09 -0600121 int ret;
122
Simon Glasse6dd8da2017-05-18 20:09:07 -0600123 node = ofnode_path("/cpus");
124 if (!ofnode_valid(node))
Simon Glass131a6452015-04-28 20:25:09 -0600125 return 0;
126
127 ret = device_bind_driver_to_node(dm_root(), "cpu_bus", "cpus", node,
128 &dev);
129
130 return ret;
131}
132
133UCLASS_DRIVER(cpu) = {
134 .id = UCLASS_CPU,
135 .name = "cpu",
136 .flags = DM_UC_FLAG_SEQ_ALIAS,
137 .init = uclass_cpu_init,
138};