| @@ -61,9 +61,12 @@ static inline void * __init xbc_alloc_mem(size_t size) · 60 unmodified lines |
| 61 | return memblock_alloc(size, SMP_CACHE_BYTES); | 61 | return memblock_alloc(size, SMP_CACHE_BYTES); |
| 62 | } | 62 | } |
| 63 | | 63 | |
| 64 | static inline void __init xbc_free_mem(void *addr, size_t size) | 64 | static inline void __init xbc_free_mem(void *addr, size_t size, bool early) |
| 65 | { | 65 | { |
| 66 | memblock_free(addr, size); | 66 | if (early) |
| | 67 | memblock_free(addr, size); |
| | 68 | else if (addr) |
| | 69 | memblock_free_late(__pa(addr), size); |
| 67 | } | 70 | } |
| 68 | | 71 | |
| 69 | #else /* !__KERNEL__ */ | 72 | #else /* !__KERNEL__ */ |
| @@ -73,7 +76,7 @@ static inline void *xbc_alloc_mem(size_t size) · 3 unmodified lines |
| 73 | return malloc(size); | 76 | return malloc(size); |
| 74 | } | 77 | } |
| 75 | | 78 | |
| 76 | static inline void xbc_free_mem(void *addr, size_t size) | 79 | static inline void xbc_free_mem(void *addr, size_t size, bool early) |
| 77 | { | 80 | { |
| 78 | free(addr); | 81 | free(addr); |
| 79 | } | 82 | } |
| @@ -898,19 +901,20 @@ static int __init xbc_parse_tree(void) · 818 unmodified lines |
| 898 | } | 901 | } |
| 899 | | 902 | |
| 900 | /** | 903 | /** |
| 901 | * xbc_exit() - Clean up all parsed bootconfig | 904 | * _xbc_exit() - Clean up all parsed bootconfig |
| | 905 | * @early: Set true if this is called before budy system is initialized. |
| 902 | * | 906 | * |
| 903 | * This clears all data structures of parsed bootconfig on memory. | 907 | * This clears all data structures of parsed bootconfig on memory. |
| 904 | * If you need to reuse xbc_init() with new boot config, you can | 908 | * If you need to reuse xbc_init() with new boot config, you can |
| 905 | * use this. | 909 | * use this. |
| 906 | */ | 910 | */ |
| 907 | void __init xbc_exit(void) | 911 | void __init _xbc_exit(bool early) |
| 908 | { | 912 | { |
| 909 | xbc_free_mem(xbc_data, xbc_data_size); | 913 | xbc_free_mem(xbc_data, xbc_data_size, early); |
| 910 | xbc_data = NULL; | 914 | xbc_data = NULL; |
| 911 | xbc_data_size = 0; | 915 | xbc_data_size = 0; |
| 912 | xbc_node_num = 0; | 916 | xbc_node_num = 0; |
| 913 | xbc_free_mem(xbc_nodes, sizeof(struct xbc_node) * XBC_NODE_MAX); | 917 | xbc_free_mem(xbc_nodes, sizeof(struct xbc_node) * XBC_NODE_MAX, early); |
| 914 | xbc_nodes = NULL; | 918 | xbc_nodes = NULL; |
| 915 | brace_index = 0; | 919 | brace_index = 0; |
| 916 | } | 920 | } |
| @@ -963,7 +967,7 @@ int __init xbc_init(const char *data, size_t size, const char **emsg, int *epos) · 46 unmodified lines |
| 963 | if (!xbc_nodes) { | 967 | if (!xbc_nodes) { |
| 964 | if (emsg) | 968 | if (emsg) |
| 965 | *emsg = "Failed to allocate bootconfig nodes"; | 969 | *emsg = "Failed to allocate bootconfig nodes"; |
| 966 | xbc_exit(); | 970 | _xbc_exit(true); |
| 967 | return -ENOMEM; | 971 | return -ENOMEM; |
| 968 | } | 972 | } |
| 969 | memset(xbc_nodes, 0, sizeof(struct xbc_node) * XBC_NODE_MAX); | 973 | memset(xbc_nodes, 0, sizeof(struct xbc_node) * XBC_NODE_MAX); |
| @@ -977,7 +981,7 @@ int __init xbc_init(const char *data, size_t size, const char **emsg, int *epos) · 7 unmodified lines |
| 977 | *epos = xbc_err_pos; | 981 | *epos = xbc_err_pos; |
| 978 | if (emsg) | 982 | if (emsg) |
| 979 | *emsg = xbc_err_msg; | 983 | *emsg = xbc_err_msg; |
| 980 | xbc_exit(); | 984 | _xbc_exit(true); |
| 981 | } else | 985 | } else |
| 982 | ret = xbc_node_num; | 986 | ret = xbc_node_num; |
| 983 | | 987 | |