]>
Commit | Line | Data |
---|---|---|
6b6024ea MY |
1 | /* |
2 | * Copyright (C) 2016 Socionext Inc. | |
3 | * Author: Masahiro Yamada <yamada.masahiro@socionext.com> | |
4 | * | |
5 | * SPDX-License-Identifier: GPL-2.0+ | |
6 | */ | |
7 | ||
8 | #include <common.h> | |
b08c8c48 | 9 | #include <linux/libfdt.h> |
6b6024ea MY |
10 | #include <asm/spin_table.h> |
11 | ||
12 | int spin_table_update_dt(void *fdt) | |
13 | { | |
14 | int cpus_offset, offset; | |
15 | const char *prop; | |
16 | int ret; | |
17 | unsigned long rsv_addr = (unsigned long)&spin_table_reserve_begin; | |
18 | unsigned long rsv_size = &spin_table_reserve_end - | |
19 | &spin_table_reserve_begin; | |
20 | ||
21 | cpus_offset = fdt_path_offset(fdt, "/cpus"); | |
22 | if (cpus_offset < 0) | |
23 | return -ENODEV; | |
24 | ||
25 | for (offset = fdt_first_subnode(fdt, cpus_offset); | |
26 | offset >= 0; | |
27 | offset = fdt_next_subnode(fdt, offset)) { | |
28 | prop = fdt_getprop(fdt, offset, "device_type", NULL); | |
29 | if (!prop || strcmp(prop, "cpu")) | |
30 | continue; | |
31 | ||
32 | /* | |
33 | * In the first loop, we check if every CPU node specifies | |
34 | * spin-table. Otherwise, just return successfully to not | |
35 | * disturb other methods, like psci. | |
36 | */ | |
37 | prop = fdt_getprop(fdt, offset, "enable-method", NULL); | |
38 | if (!prop || strcmp(prop, "spin-table")) | |
39 | return 0; | |
40 | } | |
41 | ||
42 | for (offset = fdt_first_subnode(fdt, cpus_offset); | |
43 | offset >= 0; | |
44 | offset = fdt_next_subnode(fdt, offset)) { | |
45 | prop = fdt_getprop(fdt, offset, "device_type", NULL); | |
46 | if (!prop || strcmp(prop, "cpu")) | |
47 | continue; | |
48 | ||
49 | ret = fdt_setprop_u64(fdt, offset, "cpu-release-addr", | |
50 | (unsigned long)&spin_table_cpu_release_addr); | |
51 | if (ret) | |
52 | return -ENOSPC; | |
53 | } | |
54 | ||
55 | ret = fdt_add_mem_rsv(fdt, rsv_addr, rsv_size); | |
56 | if (ret) | |
57 | return -ENOSPC; | |
58 | ||
59 | printf(" Reserved memory region for spin-table: addr=%lx size=%lx\n", | |
60 | rsv_addr, rsv_size); | |
61 | ||
62 | return 0; | |
63 | } |