hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/arch/x86/platform/olpc/olpc_dt.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * OLPC-specific OFW device tree support code.
34 *
....@@ -9,17 +10,11 @@
910 *
1011 * Adapted for sparc by David S. Miller davem@davemloft.net
1112 * Adapted for x86/OLPC by Andres Salomon <dilinger@queued.net>
12
- *
13
- * This program is free software; you can redistribute it and/or
14
- * modify it under the terms of the GNU General Public License
15
- * as published by the Free Software Foundation; either version
16
- * 2 of the License, or (at your option) any later version.
1713 */
1814
1915 #include <linux/kernel.h>
20
-#include <linux/bootmem.h>
16
+#include <linux/memblock.h>
2117 #include <linux/of.h>
22
-#include <linux/of_platform.h>
2318 #include <linux/of_pdt.h>
2419 #include <asm/olpc.h>
2520 #include <asm/olpc_ofw.h>
....@@ -141,7 +136,10 @@
141136 * fast enough on the platforms we care about while minimizing
142137 * wasted bootmem) and hand off chunks of it to callers.
143138 */
144
- res = alloc_bootmem(chunk_size);
139
+ res = memblock_alloc(chunk_size, SMP_CACHE_BYTES);
140
+ if (!res)
141
+ panic("%s: Failed to allocate %zu bytes\n", __func__,
142
+ chunk_size);
145143 BUG_ON(!res);
146144 prom_early_allocated += chunk_size;
147145 memset(res, 0, chunk_size);
....@@ -218,10 +216,26 @@
218216 return be32_to_cpu(rev);
219217 }
220218
219
+static int __init olpc_dt_compatible_match(phandle node, const char *compat)
220
+{
221
+ char buf[64], *p;
222
+ int plen, len;
223
+
224
+ plen = olpc_dt_getproperty(node, "compatible", buf, sizeof(buf));
225
+ if (plen <= 0)
226
+ return 0;
227
+
228
+ len = strlen(compat);
229
+ for (p = buf; p < buf + plen; p += strlen(p) + 1) {
230
+ if (strcmp(p, compat) == 0)
231
+ return 1;
232
+ }
233
+
234
+ return 0;
235
+}
236
+
221237 void __init olpc_dt_fixup(void)
222238 {
223
- int r;
224
- char buf[64];
225239 phandle node;
226240 u32 board_rev;
227241
....@@ -229,41 +243,66 @@
229243 if (!node)
230244 return;
231245
232
- /*
233
- * If the battery node has a compatible property, we are running a new
234
- * enough firmware and don't have fixups to make.
235
- */
236
- r = olpc_dt_getproperty(node, "compatible", buf, sizeof(buf));
237
- if (r > 0)
238
- return;
239
-
240
- pr_info("PROM DT: Old firmware detected, applying fixes\n");
241
-
242
- /* Add olpc,xo1-battery compatible marker to battery node */
243
- olpc_dt_interpret("\" /battery@0\" find-device"
244
- " \" olpc,xo1-battery\" +compatible"
245
- " device-end");
246
-
247246 board_rev = olpc_dt_get_board_revision();
248247 if (!board_rev)
249248 return;
250249
251250 if (board_rev >= olpc_board_pre(0xd0)) {
252
- /* XO-1.5: add dcon device */
253
- olpc_dt_interpret("\" /pci/display@1\" find-device"
254
- " new-device"
255
- " \" dcon\" device-name \" olpc,xo1-dcon\" +compatible"
256
- " finish-device device-end");
251
+ /* XO-1.5 */
252
+
253
+ if (olpc_dt_compatible_match(node, "olpc,xo1.5-battery"))
254
+ return;
255
+
256
+ /* Add olpc,xo1.5-battery compatible marker to battery node */
257
+ olpc_dt_interpret("\" /battery@0\" find-device");
258
+ olpc_dt_interpret(" \" olpc,xo1.5-battery\" +compatible");
259
+ olpc_dt_interpret("device-end");
260
+
261
+ if (olpc_dt_compatible_match(node, "olpc,xo1-battery")) {
262
+ /*
263
+ * If we have a olpc,xo1-battery compatible, then we're
264
+ * running a new enough firmware that already has
265
+ * the dcon node.
266
+ */
267
+ return;
268
+ }
269
+
270
+ /* Add dcon device */
271
+ olpc_dt_interpret("\" /pci/display@1\" find-device");
272
+ olpc_dt_interpret(" new-device");
273
+ olpc_dt_interpret(" \" dcon\" device-name");
274
+ olpc_dt_interpret(" \" olpc,xo1-dcon\" +compatible");
275
+ olpc_dt_interpret(" finish-device");
276
+ olpc_dt_interpret("device-end");
257277 } else {
258
- /* XO-1: add dcon device, mark RTC as olpc,xo1-rtc */
259
- olpc_dt_interpret("\" /pci/display@1,1\" find-device"
260
- " new-device"
261
- " \" dcon\" device-name \" olpc,xo1-dcon\" +compatible"
262
- " finish-device device-end"
263
- " \" /rtc\" find-device"
264
- " \" olpc,xo1-rtc\" +compatible"
265
- " device-end");
278
+ /* XO-1 */
279
+
280
+ if (olpc_dt_compatible_match(node, "olpc,xo1-battery")) {
281
+ /*
282
+ * If we have a olpc,xo1-battery compatible, then we're
283
+ * running a new enough firmware that already has
284
+ * the dcon and RTC nodes.
285
+ */
286
+ return;
287
+ }
288
+
289
+ /* Add dcon device, mark RTC as olpc,xo1-rtc */
290
+ olpc_dt_interpret("\" /pci/display@1,1\" find-device");
291
+ olpc_dt_interpret(" new-device");
292
+ olpc_dt_interpret(" \" dcon\" device-name");
293
+ olpc_dt_interpret(" \" olpc,xo1-dcon\" +compatible");
294
+ olpc_dt_interpret(" finish-device");
295
+ olpc_dt_interpret("device-end");
296
+
297
+ olpc_dt_interpret("\" /rtc\" find-device");
298
+ olpc_dt_interpret(" \" olpc,xo1-rtc\" +compatible");
299
+ olpc_dt_interpret("device-end");
266300 }
301
+
302
+ /* Add olpc,xo1-battery compatible marker to battery node */
303
+ olpc_dt_interpret("\" /battery@0\" find-device");
304
+ olpc_dt_interpret(" \" olpc,xo1-battery\" +compatible");
305
+ olpc_dt_interpret("device-end");
267306 }
268307
269308 void __init olpc_dt_build_devicetree(void)
....@@ -285,20 +324,3 @@
285324 pr_info("PROM DT: Built device tree with %u bytes of memory.\n",
286325 prom_early_allocated);
287326 }
288
-
289
-/* A list of DT node/bus matches that we want to expose as platform devices */
290
-static struct of_device_id __initdata of_ids[] = {
291
- { .compatible = "olpc,xo1-battery" },
292
- { .compatible = "olpc,xo1-dcon" },
293
- { .compatible = "olpc,xo1-rtc" },
294
- {},
295
-};
296
-
297
-static int __init olpc_create_platform_devices(void)
298
-{
299
- if (machine_is_olpc())
300
- return of_platform_bus_probe(NULL, of_ids, NULL);
301
- else
302
- return 0;
303
-}
304
-device_initcall(olpc_create_platform_devices);