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