forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-11 04dd17822334871b23ea2862f7798fb0e0007777
kernel/arch/powerpc/mm/drmem.c
....@@ -1,12 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Dynamic reconfiguration memory support
34 *
45 * Copyright 2017 IBM Corporation
5
- *
6
- * This program is free software; you can redistribute it and/or
7
- * modify it under the terms of the GNU General Public License
8
- * as published by the Free Software Foundation; either version
9
- * 2 of the License, or (at your option) any later version.
106 */
117
128 #define pr_fmt(fmt) "drmem: " fmt
....@@ -17,6 +13,8 @@
1713 #include <linux/memblock.h>
1814 #include <asm/prom.h>
1915 #include <asm/drmem.h>
16
+
17
+static int n_root_addr_cells, n_root_size_cells;
2018
2119 static struct drmem_lmb_info __drmem_info;
2220 struct drmem_lmb_info *drmem_info = &__drmem_info;
....@@ -193,12 +191,13 @@
193191 return rc;
194192 }
195193
196
-static void __init read_drconf_v1_cell(struct drmem_lmb *lmb,
194
+static void read_drconf_v1_cell(struct drmem_lmb *lmb,
197195 const __be32 **prop)
198196 {
199197 const __be32 *p = *prop;
200198
201
- lmb->base_addr = dt_mem_next_cell(dt_root_addr_cells, &p);
199
+ lmb->base_addr = of_read_number(p, n_root_addr_cells);
200
+ p += n_root_addr_cells;
202201 lmb->drc_index = of_read_number(p++, 1);
203202
204203 p++; /* skip reserved field */
....@@ -209,29 +208,33 @@
209208 *prop = p;
210209 }
211210
212
-static void __init __walk_drmem_v1_lmbs(const __be32 *prop, const __be32 *usm,
213
- void (*func)(struct drmem_lmb *, const __be32 **))
211
+static int
212
+__walk_drmem_v1_lmbs(const __be32 *prop, const __be32 *usm, void *data,
213
+ int (*func)(struct drmem_lmb *, const __be32 **, void *))
214214 {
215215 struct drmem_lmb lmb;
216216 u32 i, n_lmbs;
217
+ int ret = 0;
217218
218219 n_lmbs = of_read_number(prop++, 1);
219
- if (n_lmbs == 0)
220
- return;
221
-
222220 for (i = 0; i < n_lmbs; i++) {
223221 read_drconf_v1_cell(&lmb, &prop);
224
- func(&lmb, &usm);
222
+ ret = func(&lmb, &usm, data);
223
+ if (ret)
224
+ break;
225225 }
226
+
227
+ return ret;
226228 }
227229
228
-static void __init read_drconf_v2_cell(struct of_drconf_cell_v2 *dr_cell,
230
+static void read_drconf_v2_cell(struct of_drconf_cell_v2 *dr_cell,
229231 const __be32 **prop)
230232 {
231233 const __be32 *p = *prop;
232234
233235 dr_cell->seq_lmbs = of_read_number(p++, 1);
234
- dr_cell->base_addr = dt_mem_next_cell(dt_root_addr_cells, &p);
236
+ dr_cell->base_addr = of_read_number(p, n_root_addr_cells);
237
+ p += n_root_addr_cells;
235238 dr_cell->drc_index = of_read_number(p++, 1);
236239 dr_cell->aa_index = of_read_number(p++, 1);
237240 dr_cell->flags = of_read_number(p++, 1);
....@@ -239,17 +242,16 @@
239242 *prop = p;
240243 }
241244
242
-static void __init __walk_drmem_v2_lmbs(const __be32 *prop, const __be32 *usm,
243
- void (*func)(struct drmem_lmb *, const __be32 **))
245
+static int
246
+__walk_drmem_v2_lmbs(const __be32 *prop, const __be32 *usm, void *data,
247
+ int (*func)(struct drmem_lmb *, const __be32 **, void *))
244248 {
245249 struct of_drconf_cell_v2 dr_cell;
246250 struct drmem_lmb lmb;
247251 u32 i, j, lmb_sets;
252
+ int ret = 0;
248253
249254 lmb_sets = of_read_number(prop++, 1);
250
- if (lmb_sets == 0)
251
- return;
252
-
253255 for (i = 0; i < lmb_sets; i++) {
254256 read_drconf_v2_cell(&dr_cell, &prop);
255257
....@@ -263,21 +265,29 @@
263265 lmb.aa_index = dr_cell.aa_index;
264266 lmb.flags = dr_cell.flags;
265267
266
- func(&lmb, &usm);
268
+ ret = func(&lmb, &usm, data);
269
+ if (ret)
270
+ break;
267271 }
268272 }
273
+
274
+ return ret;
269275 }
270276
271277 #ifdef CONFIG_PPC_PSERIES
272
-void __init walk_drmem_lmbs_early(unsigned long node,
273
- void (*func)(struct drmem_lmb *, const __be32 **))
278
+int __init walk_drmem_lmbs_early(unsigned long node, void *data,
279
+ int (*func)(struct drmem_lmb *, const __be32 **, void *))
274280 {
275281 const __be32 *prop, *usm;
276
- int len;
282
+ int len, ret = -ENODEV;
277283
278284 prop = of_get_flat_dt_prop(node, "ibm,lmb-size", &len);
279285 if (!prop || len < dt_root_size_cells * sizeof(__be32))
280
- return;
286
+ return ret;
287
+
288
+ /* Get the address & size cells */
289
+ n_root_addr_cells = dt_root_addr_cells;
290
+ n_root_size_cells = dt_root_size_cells;
281291
282292 drmem_info->lmb_size = dt_mem_next_cell(dt_root_size_cells, &prop);
283293
....@@ -285,20 +295,21 @@
285295
286296 prop = of_get_flat_dt_prop(node, "ibm,dynamic-memory", &len);
287297 if (prop) {
288
- __walk_drmem_v1_lmbs(prop, usm, func);
298
+ ret = __walk_drmem_v1_lmbs(prop, usm, data, func);
289299 } else {
290300 prop = of_get_flat_dt_prop(node, "ibm,dynamic-memory-v2",
291301 &len);
292302 if (prop)
293
- __walk_drmem_v2_lmbs(prop, usm, func);
303
+ ret = __walk_drmem_v2_lmbs(prop, usm, data, func);
294304 }
295305
296306 memblock_dump_all();
307
+ return ret;
297308 }
298309
299310 #endif
300311
301
-static int __init init_drmem_lmb_size(struct device_node *dn)
312
+static int init_drmem_lmb_size(struct device_node *dn)
302313 {
303314 const __be32 *prop;
304315 int len;
....@@ -307,12 +318,12 @@
307318 return 0;
308319
309320 prop = of_get_property(dn, "ibm,lmb-size", &len);
310
- if (!prop || len < dt_root_size_cells * sizeof(__be32)) {
321
+ if (!prop || len < n_root_size_cells * sizeof(__be32)) {
311322 pr_info("Could not determine LMB size\n");
312323 return -1;
313324 }
314325
315
- drmem_info->lmb_size = dt_mem_next_cell(dt_root_size_cells, &prop);
326
+ drmem_info->lmb_size = of_read_number(prop, n_root_size_cells);
316327 return 0;
317328 }
318329
....@@ -333,24 +344,36 @@
333344 return prop;
334345 }
335346
336
-void __init walk_drmem_lmbs(struct device_node *dn,
337
- void (*func)(struct drmem_lmb *, const __be32 **))
347
+int walk_drmem_lmbs(struct device_node *dn, void *data,
348
+ int (*func)(struct drmem_lmb *, const __be32 **, void *))
338349 {
339350 const __be32 *prop, *usm;
351
+ int ret = -ENODEV;
352
+
353
+ if (!of_root)
354
+ return ret;
355
+
356
+ /* Get the address & size cells */
357
+ of_node_get(of_root);
358
+ n_root_addr_cells = of_n_addr_cells(of_root);
359
+ n_root_size_cells = of_n_size_cells(of_root);
360
+ of_node_put(of_root);
340361
341362 if (init_drmem_lmb_size(dn))
342
- return;
363
+ return ret;
343364
344365 usm = of_get_usable_memory(dn);
345366
346367 prop = of_get_property(dn, "ibm,dynamic-memory", NULL);
347368 if (prop) {
348
- __walk_drmem_v1_lmbs(prop, usm, func);
369
+ ret = __walk_drmem_v1_lmbs(prop, usm, data, func);
349370 } else {
350371 prop = of_get_property(dn, "ibm,dynamic-memory-v2", NULL);
351372 if (prop)
352
- __walk_drmem_v2_lmbs(prop, usm, func);
373
+ ret = __walk_drmem_v2_lmbs(prop, usm, data, func);
353374 }
375
+
376
+ return ret;
354377 }
355378
356379 static void __init init_drmem_v1_lmbs(const __be32 *prop)