unittest.c (bba73071b6f71be0a101658d7c13866e30b264a6) unittest.c (39a751a4cb7e4798f0ce1169ec92de4a1aae39e3)
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Self tests for device tree subsystem
4 */
5
6#define pr_fmt(fmt) "### dt-test ### " fmt
7
8#include <linux/bootmem.h>

--- 31 unchanged lines hidden (view full) ---

40 pr_err("FAIL %s():%i " fmt, __func__, __LINE__, ##__VA_ARGS__); \
41 } else { \
42 unittest_results.passed++; \
43 pr_debug("pass %s():%i\n", __func__, __LINE__); \
44 } \
45 failed; \
46})
47
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Self tests for device tree subsystem
4 */
5
6#define pr_fmt(fmt) "### dt-test ### " fmt
7
8#include <linux/bootmem.h>

--- 31 unchanged lines hidden (view full) ---

40 pr_err("FAIL %s():%i " fmt, __func__, __LINE__, ##__VA_ARGS__); \
41 } else { \
42 unittest_results.passed++; \
43 pr_debug("pass %s():%i\n", __func__, __LINE__); \
44 } \
45 failed; \
46})
47
48static int __init overlay_data_apply(const char *overlay_name, int *overlay_id);
49
48static void __init of_unittest_find_node_by_name(void)
49{
50 struct device_node *np;
51 const char *options, *name;
52
53 np = of_find_node_by_path("/testcase-data");
54 name = kasprintf(GFP_KERNEL, "%pOF", np);
55 unittest(np && !strcmp("/testcase-data", name),

--- 936 unchanged lines hidden (view full) ---

992 }
993 of_fdt_unflatten_tree(unittest_data, NULL, &unittest_data_node);
994 if (!unittest_data_node) {
995 pr_warn("%s: No tree to attach; not running tests\n", __func__);
996 return -ENODATA;
997 }
998
999 /*
50static void __init of_unittest_find_node_by_name(void)
51{
52 struct device_node *np;
53 const char *options, *name;
54
55 np = of_find_node_by_path("/testcase-data");
56 name = kasprintf(GFP_KERNEL, "%pOF", np);
57 unittest(np && !strcmp("/testcase-data", name),

--- 936 unchanged lines hidden (view full) ---

994 }
995 of_fdt_unflatten_tree(unittest_data, NULL, &unittest_data_node);
996 if (!unittest_data_node) {
997 pr_warn("%s: No tree to attach; not running tests\n", __func__);
998 return -ENODATA;
999 }
1000
1001 /*
1000 * This lock normally encloses of_overlay_apply() as well as
1001 * of_resolve_phandles().
1002 * This lock normally encloses of_resolve_phandles()
1002 */
1003 of_overlay_mutex_lock();
1004
1005 rc = of_resolve_phandles(unittest_data_node);
1006 if (rc) {
1007 pr_err("%s: Failed to resolve phandles (rc=%i)\n", __func__, rc);
1008 of_overlay_mutex_unlock();
1009 return -EINVAL;

--- 176 unchanged lines hidden (view full) ---

1186 case PDEV_OVERLAY:
1187 return of_path_platform_device_exists(path);
1188 case I2C_OVERLAY:
1189 return of_path_i2c_client_exists(path);
1190 }
1191 return 0;
1192}
1193
1003 */
1004 of_overlay_mutex_lock();
1005
1006 rc = of_resolve_phandles(unittest_data_node);
1007 if (rc) {
1008 pr_err("%s: Failed to resolve phandles (rc=%i)\n", __func__, rc);
1009 of_overlay_mutex_unlock();
1010 return -EINVAL;

--- 176 unchanged lines hidden (view full) ---

1187 case PDEV_OVERLAY:
1188 return of_path_platform_device_exists(path);
1189 case I2C_OVERLAY:
1190 return of_path_i2c_client_exists(path);
1191 }
1192 return 0;
1193}
1194
1194static const char *overlay_path(int nr)
1195static const char *overlay_name_from_nr(int nr)
1195{
1196 static char buf[256];
1197
1198 snprintf(buf, sizeof(buf) - 1,
1196{
1197 static char buf[256];
1198
1199 snprintf(buf, sizeof(buf) - 1,
1199 "/testcase-data/overlay%d", nr);
1200 "overlay_%d", nr);
1200 buf[sizeof(buf) - 1] = '\0';
1201
1202 return buf;
1203}
1204
1205static const char *bus_path = "/testcase-data/overlay-node/test-bus";
1206
1207/* it is guaranteed that overlay ids are assigned in sequence */

--- 50 unchanged lines hidden (view full) ---

1258 continue;
1259 }
1260
1261 overlay_id_bits[BIT_WORD(id)] &= ~BIT_MASK(id);
1262 }
1263 } while (defers > 0);
1264}
1265
1201 buf[sizeof(buf) - 1] = '\0';
1202
1203 return buf;
1204}
1205
1206static const char *bus_path = "/testcase-data/overlay-node/test-bus";
1207
1208/* it is guaranteed that overlay ids are assigned in sequence */

--- 50 unchanged lines hidden (view full) ---

1259 continue;
1260 }
1261
1262 overlay_id_bits[BIT_WORD(id)] &= ~BIT_MASK(id);
1263 }
1264 } while (defers > 0);
1265}
1266
1266static int of_unittest_apply_overlay(int overlay_nr, int unittest_nr,
1267static int __init of_unittest_apply_overlay(int overlay_nr, int unittest_nr,
1267 int *overlay_id)
1268{
1269 struct device_node *np = NULL;
1268 int *overlay_id)
1269{
1270 struct device_node *np = NULL;
1271 const char *overlay_name;
1270 int ret;
1271
1272 int ret;
1273
1272 np = of_find_node_by_path(overlay_path(overlay_nr));
1273 if (np == NULL) {
1274 unittest(0, "could not find overlay node @\"%s\"\n",
1275 overlay_path(overlay_nr));
1276 ret = -EINVAL;
1277 goto out;
1278 }
1274 overlay_name = overlay_name_from_nr(overlay_nr);
1279
1275
1280 *overlay_id = 0;
1281 ret = of_overlay_apply(np, overlay_id);
1282 if (ret < 0) {
1283 unittest(0, "could not create overlay from \"%s\"\n",
1284 overlay_path(overlay_nr));
1276 ret = overlay_data_apply(overlay_name, overlay_id);
1277 if (!ret) {
1278 unittest(0, "could not apply overlay \"%s\"\n",
1279 overlay_name);
1285 goto out;
1286 }
1287 of_unittest_track_overlay(*overlay_id);
1288
1289 ret = 0;
1290
1291out:
1292 of_node_put(np);
1293
1294 return ret;
1295}
1296
1297/* apply an overlay while checking before and after states */
1280 goto out;
1281 }
1282 of_unittest_track_overlay(*overlay_id);
1283
1284 ret = 0;
1285
1286out:
1287 of_node_put(np);
1288
1289 return ret;
1290}
1291
1292/* apply an overlay while checking before and after states */
1298static int of_unittest_apply_overlay_check(int overlay_nr, int unittest_nr,
1299 int before, int after, enum overlay_type ovtype)
1293static int __init of_unittest_apply_overlay_check(int overlay_nr,
1294 int unittest_nr, int before, int after,
1295 enum overlay_type ovtype)
1300{
1301 int ret, ovcs_id;
1302
1303 /* unittest device must not be in before state */
1304 if (of_unittest_device_exists(unittest_nr, ovtype) != before) {
1296{
1297 int ret, ovcs_id;
1298
1299 /* unittest device must not be in before state */
1300 if (of_unittest_device_exists(unittest_nr, ovtype) != before) {
1305 unittest(0, "overlay @\"%s\" with device @\"%s\" %s\n",
1306 overlay_path(overlay_nr),
1301 unittest(0, "%s with device @\"%s\" %s\n",
1302 overlay_name_from_nr(overlay_nr),
1307 unittest_path(unittest_nr, ovtype),
1308 !before ? "enabled" : "disabled");
1309 return -EINVAL;
1310 }
1311
1312 ovcs_id = 0;
1313 ret = of_unittest_apply_overlay(overlay_nr, unittest_nr, &ovcs_id);
1314 if (ret != 0) {
1315 /* of_unittest_apply_overlay already called unittest() */
1316 return ret;
1317 }
1318
1319 /* unittest device must be to set to after state */
1320 if (of_unittest_device_exists(unittest_nr, ovtype) != after) {
1303 unittest_path(unittest_nr, ovtype),
1304 !before ? "enabled" : "disabled");
1305 return -EINVAL;
1306 }
1307
1308 ovcs_id = 0;
1309 ret = of_unittest_apply_overlay(overlay_nr, unittest_nr, &ovcs_id);
1310 if (ret != 0) {
1311 /* of_unittest_apply_overlay already called unittest() */
1312 return ret;
1313 }
1314
1315 /* unittest device must be to set to after state */
1316 if (of_unittest_device_exists(unittest_nr, ovtype) != after) {
1321 unittest(0, "overlay @\"%s\" failed to create @\"%s\" %s\n",
1322 overlay_path(overlay_nr),
1317 unittest(0, "%s failed to create @\"%s\" %s\n",
1318 overlay_name_from_nr(overlay_nr),
1323 unittest_path(unittest_nr, ovtype),
1324 !after ? "enabled" : "disabled");
1325 return -EINVAL;
1326 }
1327
1328 return 0;
1329}
1330
1331/* apply an overlay and then revert it while checking before, after states */
1319 unittest_path(unittest_nr, ovtype),
1320 !after ? "enabled" : "disabled");
1321 return -EINVAL;
1322 }
1323
1324 return 0;
1325}
1326
1327/* apply an overlay and then revert it while checking before, after states */
1332static int of_unittest_apply_revert_overlay_check(int overlay_nr,
1328static int __init of_unittest_apply_revert_overlay_check(int overlay_nr,
1333 int unittest_nr, int before, int after,
1334 enum overlay_type ovtype)
1335{
1336 int ret, ovcs_id;
1337
1338 /* unittest device must be in before state */
1339 if (of_unittest_device_exists(unittest_nr, ovtype) != before) {
1329 int unittest_nr, int before, int after,
1330 enum overlay_type ovtype)
1331{
1332 int ret, ovcs_id;
1333
1334 /* unittest device must be in before state */
1335 if (of_unittest_device_exists(unittest_nr, ovtype) != before) {
1340 unittest(0, "overlay @\"%s\" with device @\"%s\" %s\n",
1341 overlay_path(overlay_nr),
1336 unittest(0, "%s with device @\"%s\" %s\n",
1337 overlay_name_from_nr(overlay_nr),
1342 unittest_path(unittest_nr, ovtype),
1343 !before ? "enabled" : "disabled");
1344 return -EINVAL;
1345 }
1346
1347 /* apply the overlay */
1348 ovcs_id = 0;
1349 ret = of_unittest_apply_overlay(overlay_nr, unittest_nr, &ovcs_id);
1350 if (ret != 0) {
1351 /* of_unittest_apply_overlay already called unittest() */
1352 return ret;
1353 }
1354
1355 /* unittest device must be in after state */
1356 if (of_unittest_device_exists(unittest_nr, ovtype) != after) {
1338 unittest_path(unittest_nr, ovtype),
1339 !before ? "enabled" : "disabled");
1340 return -EINVAL;
1341 }
1342
1343 /* apply the overlay */
1344 ovcs_id = 0;
1345 ret = of_unittest_apply_overlay(overlay_nr, unittest_nr, &ovcs_id);
1346 if (ret != 0) {
1347 /* of_unittest_apply_overlay already called unittest() */
1348 return ret;
1349 }
1350
1351 /* unittest device must be in after state */
1352 if (of_unittest_device_exists(unittest_nr, ovtype) != after) {
1357 unittest(0, "overlay @\"%s\" failed to create @\"%s\" %s\n",
1358 overlay_path(overlay_nr),
1353 unittest(0, "%s failed to create @\"%s\" %s\n",
1354 overlay_name_from_nr(overlay_nr),
1359 unittest_path(unittest_nr, ovtype),
1360 !after ? "enabled" : "disabled");
1361 return -EINVAL;
1362 }
1363
1364 ret = of_overlay_remove(&ovcs_id);
1365 if (ret != 0) {
1355 unittest_path(unittest_nr, ovtype),
1356 !after ? "enabled" : "disabled");
1357 return -EINVAL;
1358 }
1359
1360 ret = of_overlay_remove(&ovcs_id);
1361 if (ret != 0) {
1366 unittest(0, "overlay @\"%s\" failed to be destroyed @\"%s\"\n",
1367 overlay_path(overlay_nr),
1362 unittest(0, "%s failed to be destroyed @\"%s\"\n",
1363 overlay_name_from_nr(overlay_nr),
1368 unittest_path(unittest_nr, ovtype));
1369 return ret;
1370 }
1371
1372 /* unittest device must be again in before state */
1373 if (of_unittest_device_exists(unittest_nr, PDEV_OVERLAY) != before) {
1364 unittest_path(unittest_nr, ovtype));
1365 return ret;
1366 }
1367
1368 /* unittest device must be again in before state */
1369 if (of_unittest_device_exists(unittest_nr, PDEV_OVERLAY) != before) {
1374 unittest(0, "overlay @\"%s\" with device @\"%s\" %s\n",
1375 overlay_path(overlay_nr),
1370 unittest(0, "%s with device @\"%s\" %s\n",
1371 overlay_name_from_nr(overlay_nr),
1376 unittest_path(unittest_nr, ovtype),
1377 !before ? "enabled" : "disabled");
1378 return -EINVAL;
1379 }
1380
1381 return 0;
1382}
1383
1384/* test activation of device */
1372 unittest_path(unittest_nr, ovtype),
1373 !before ? "enabled" : "disabled");
1374 return -EINVAL;
1375 }
1376
1377 return 0;
1378}
1379
1380/* test activation of device */
1385static void of_unittest_overlay_0(void)
1381static void __init of_unittest_overlay_0(void)
1386{
1387 int ret;
1388
1389 /* device should enable */
1390 ret = of_unittest_apply_overlay_check(0, 0, 0, 1, PDEV_OVERLAY);
1391 if (ret != 0)
1392 return;
1393
1394 unittest(1, "overlay test %d passed\n", 0);
1395}
1396
1397/* test deactivation of device */
1382{
1383 int ret;
1384
1385 /* device should enable */
1386 ret = of_unittest_apply_overlay_check(0, 0, 0, 1, PDEV_OVERLAY);
1387 if (ret != 0)
1388 return;
1389
1390 unittest(1, "overlay test %d passed\n", 0);
1391}
1392
1393/* test deactivation of device */
1398static void of_unittest_overlay_1(void)
1394static void __init of_unittest_overlay_1(void)
1399{
1400 int ret;
1401
1402 /* device should disable */
1403 ret = of_unittest_apply_overlay_check(1, 1, 1, 0, PDEV_OVERLAY);
1404 if (ret != 0)
1405 return;
1406
1407 unittest(1, "overlay test %d passed\n", 1);
1408}
1409
1410/* test activation of device */
1395{
1396 int ret;
1397
1398 /* device should disable */
1399 ret = of_unittest_apply_overlay_check(1, 1, 1, 0, PDEV_OVERLAY);
1400 if (ret != 0)
1401 return;
1402
1403 unittest(1, "overlay test %d passed\n", 1);
1404}
1405
1406/* test activation of device */
1411static void of_unittest_overlay_2(void)
1407static void __init of_unittest_overlay_2(void)
1412{
1413 int ret;
1414
1415 /* device should enable */
1416 ret = of_unittest_apply_overlay_check(2, 2, 0, 1, PDEV_OVERLAY);
1417 if (ret != 0)
1418 return;
1419
1420 unittest(1, "overlay test %d passed\n", 2);
1421}
1422
1423/* test deactivation of device */
1408{
1409 int ret;
1410
1411 /* device should enable */
1412 ret = of_unittest_apply_overlay_check(2, 2, 0, 1, PDEV_OVERLAY);
1413 if (ret != 0)
1414 return;
1415
1416 unittest(1, "overlay test %d passed\n", 2);
1417}
1418
1419/* test deactivation of device */
1424static void of_unittest_overlay_3(void)
1420static void __init of_unittest_overlay_3(void)
1425{
1426 int ret;
1427
1428 /* device should disable */
1429 ret = of_unittest_apply_overlay_check(3, 3, 1, 0, PDEV_OVERLAY);
1430 if (ret != 0)
1431 return;
1432
1433 unittest(1, "overlay test %d passed\n", 3);
1434}
1435
1436/* test activation of a full device node */
1421{
1422 int ret;
1423
1424 /* device should disable */
1425 ret = of_unittest_apply_overlay_check(3, 3, 1, 0, PDEV_OVERLAY);
1426 if (ret != 0)
1427 return;
1428
1429 unittest(1, "overlay test %d passed\n", 3);
1430}
1431
1432/* test activation of a full device node */
1437static void of_unittest_overlay_4(void)
1433static void __init of_unittest_overlay_4(void)
1438{
1439 int ret;
1440
1441 /* device should disable */
1442 ret = of_unittest_apply_overlay_check(4, 4, 0, 1, PDEV_OVERLAY);
1443 if (ret != 0)
1444 return;
1445
1446 unittest(1, "overlay test %d passed\n", 4);
1447}
1448
1449/* test overlay apply/revert sequence */
1434{
1435 int ret;
1436
1437 /* device should disable */
1438 ret = of_unittest_apply_overlay_check(4, 4, 0, 1, PDEV_OVERLAY);
1439 if (ret != 0)
1440 return;
1441
1442 unittest(1, "overlay test %d passed\n", 4);
1443}
1444
1445/* test overlay apply/revert sequence */
1450static void of_unittest_overlay_5(void)
1446static void __init of_unittest_overlay_5(void)
1451{
1452 int ret;
1453
1454 /* device should disable */
1455 ret = of_unittest_apply_revert_overlay_check(5, 5, 0, 1, PDEV_OVERLAY);
1456 if (ret != 0)
1457 return;
1458
1459 unittest(1, "overlay test %d passed\n", 5);
1460}
1461
1462/* test overlay application in sequence */
1447{
1448 int ret;
1449
1450 /* device should disable */
1451 ret = of_unittest_apply_revert_overlay_check(5, 5, 0, 1, PDEV_OVERLAY);
1452 if (ret != 0)
1453 return;
1454
1455 unittest(1, "overlay test %d passed\n", 5);
1456}
1457
1458/* test overlay application in sequence */
1463static void of_unittest_overlay_6(void)
1459static void __init of_unittest_overlay_6(void)
1464{
1460{
1465 struct device_node *np;
1466 int ret, i, ov_id[2], ovcs_id;
1467 int overlay_nr = 6, unittest_nr = 6;
1468 int before = 0, after = 1;
1461 int ret, i, ov_id[2], ovcs_id;
1462 int overlay_nr = 6, unittest_nr = 6;
1463 int before = 0, after = 1;
1464 const char *overlay_name;
1469
1470 /* unittest device must be in before state */
1471 for (i = 0; i < 2; i++) {
1472 if (of_unittest_device_exists(unittest_nr + i, PDEV_OVERLAY)
1473 != before) {
1465
1466 /* unittest device must be in before state */
1467 for (i = 0; i < 2; i++) {
1468 if (of_unittest_device_exists(unittest_nr + i, PDEV_OVERLAY)
1469 != before) {
1474 unittest(0, "overlay @\"%s\" with device @\"%s\" %s\n",
1475 overlay_path(overlay_nr + i),
1470 unittest(0, "%s with device @\"%s\" %s\n",
1471 overlay_name_from_nr(overlay_nr + i),
1476 unittest_path(unittest_nr + i,
1477 PDEV_OVERLAY),
1478 !before ? "enabled" : "disabled");
1479 return;
1480 }
1481 }
1482
1483 /* apply the overlays */
1484 for (i = 0; i < 2; i++) {
1485
1472 unittest_path(unittest_nr + i,
1473 PDEV_OVERLAY),
1474 !before ? "enabled" : "disabled");
1475 return;
1476 }
1477 }
1478
1479 /* apply the overlays */
1480 for (i = 0; i < 2; i++) {
1481
1486 np = of_find_node_by_path(overlay_path(overlay_nr + i));
1487 if (np == NULL) {
1488 unittest(0, "could not find overlay node @\"%s\"\n",
1489 overlay_path(overlay_nr + i));
1490 return;
1491 }
1482 overlay_name = overlay_name_from_nr(overlay_nr + i);
1492
1483
1493 ovcs_id = 0;
1494 ret = of_overlay_apply(np, &ovcs_id);
1495 if (ret < 0) {
1496 unittest(0, "could not create overlay from \"%s\"\n",
1497 overlay_path(overlay_nr + i));
1484 ret = overlay_data_apply(overlay_name, &ovcs_id);
1485 if (!ret) {
1486 unittest(0, "could not apply overlay \"%s\"\n",
1487 overlay_name);
1498 return;
1499 }
1500 ov_id[i] = ovcs_id;
1501 of_unittest_track_overlay(ov_id[i]);
1502 }
1503
1504 for (i = 0; i < 2; i++) {
1505 /* unittest device must be in after state */
1506 if (of_unittest_device_exists(unittest_nr + i, PDEV_OVERLAY)
1507 != after) {
1508 unittest(0, "overlay @\"%s\" failed @\"%s\" %s\n",
1488 return;
1489 }
1490 ov_id[i] = ovcs_id;
1491 of_unittest_track_overlay(ov_id[i]);
1492 }
1493
1494 for (i = 0; i < 2; i++) {
1495 /* unittest device must be in after state */
1496 if (of_unittest_device_exists(unittest_nr + i, PDEV_OVERLAY)
1497 != after) {
1498 unittest(0, "overlay @\"%s\" failed @\"%s\" %s\n",
1509 overlay_path(overlay_nr + i),
1499 overlay_name_from_nr(overlay_nr + i),
1510 unittest_path(unittest_nr + i,
1511 PDEV_OVERLAY),
1512 !after ? "enabled" : "disabled");
1513 return;
1514 }
1515 }
1516
1517 for (i = 1; i >= 0; i--) {
1518 ovcs_id = ov_id[i];
1519 ret = of_overlay_remove(&ovcs_id);
1520 if (ret != 0) {
1500 unittest_path(unittest_nr + i,
1501 PDEV_OVERLAY),
1502 !after ? "enabled" : "disabled");
1503 return;
1504 }
1505 }
1506
1507 for (i = 1; i >= 0; i--) {
1508 ovcs_id = ov_id[i];
1509 ret = of_overlay_remove(&ovcs_id);
1510 if (ret != 0) {
1521 unittest(0, "overlay @\"%s\" failed destroy @\"%s\"\n",
1522 overlay_path(overlay_nr + i),
1511 unittest(0, "%s failed destroy @\"%s\"\n",
1512 overlay_name_from_nr(overlay_nr + i),
1523 unittest_path(unittest_nr + i,
1524 PDEV_OVERLAY));
1525 return;
1526 }
1527 of_unittest_untrack_overlay(ov_id[i]);
1528 }
1529
1530 for (i = 0; i < 2; i++) {
1531 /* unittest device must be again in before state */
1532 if (of_unittest_device_exists(unittest_nr + i, PDEV_OVERLAY)
1533 != before) {
1513 unittest_path(unittest_nr + i,
1514 PDEV_OVERLAY));
1515 return;
1516 }
1517 of_unittest_untrack_overlay(ov_id[i]);
1518 }
1519
1520 for (i = 0; i < 2; i++) {
1521 /* unittest device must be again in before state */
1522 if (of_unittest_device_exists(unittest_nr + i, PDEV_OVERLAY)
1523 != before) {
1534 unittest(0, "overlay @\"%s\" with device @\"%s\" %s\n",
1535 overlay_path(overlay_nr + i),
1524 unittest(0, "%s with device @\"%s\" %s\n",
1525 overlay_name_from_nr(overlay_nr + i),
1536 unittest_path(unittest_nr + i,
1537 PDEV_OVERLAY),
1538 !before ? "enabled" : "disabled");
1539 return;
1540 }
1541 }
1542
1543 unittest(1, "overlay test %d passed\n", 6);
1544}
1545
1546/* test overlay application in sequence */
1526 unittest_path(unittest_nr + i,
1527 PDEV_OVERLAY),
1528 !before ? "enabled" : "disabled");
1529 return;
1530 }
1531 }
1532
1533 unittest(1, "overlay test %d passed\n", 6);
1534}
1535
1536/* test overlay application in sequence */
1547static void of_unittest_overlay_8(void)
1537static void __init of_unittest_overlay_8(void)
1548{
1538{
1549 struct device_node *np;
1550 int ret, i, ov_id[2], ovcs_id;
1551 int overlay_nr = 8, unittest_nr = 8;
1539 int ret, i, ov_id[2], ovcs_id;
1540 int overlay_nr = 8, unittest_nr = 8;
1541 const char *overlay_name;
1552
1553 /* we don't care about device state in this test */
1554
1555 /* apply the overlays */
1556 for (i = 0; i < 2; i++) {
1557
1542
1543 /* we don't care about device state in this test */
1544
1545 /* apply the overlays */
1546 for (i = 0; i < 2; i++) {
1547
1558 np = of_find_node_by_path(overlay_path(overlay_nr + i));
1559 if (np == NULL) {
1560 unittest(0, "could not find overlay node @\"%s\"\n",
1561 overlay_path(overlay_nr + i));
1562 return;
1563 }
1548 overlay_name = overlay_name_from_nr(overlay_nr + i);
1564
1549
1565 ovcs_id = 0;
1566 ret = of_overlay_apply(np, &ovcs_id);
1550 ret = overlay_data_apply(overlay_name, &ovcs_id);
1567 if (ret < 0) {
1551 if (ret < 0) {
1568 unittest(0, "could not create overlay from \"%s\"\n",
1569 overlay_path(overlay_nr + i));
1552 unittest(0, "could not apply overlay \"%s\"\n",
1553 overlay_name);
1570 return;
1571 }
1572 ov_id[i] = ovcs_id;
1573 of_unittest_track_overlay(ov_id[i]);
1574 }
1575
1576 /* now try to remove first overlay (it should fail) */
1577 ovcs_id = ov_id[0];
1578 ret = of_overlay_remove(&ovcs_id);
1579 if (ret == 0) {
1554 return;
1555 }
1556 ov_id[i] = ovcs_id;
1557 of_unittest_track_overlay(ov_id[i]);
1558 }
1559
1560 /* now try to remove first overlay (it should fail) */
1561 ovcs_id = ov_id[0];
1562 ret = of_overlay_remove(&ovcs_id);
1563 if (ret == 0) {
1580 unittest(0, "overlay @\"%s\" was destroyed @\"%s\"\n",
1581 overlay_path(overlay_nr + 0),
1564 unittest(0, "%s was destroyed @\"%s\"\n",
1565 overlay_name_from_nr(overlay_nr + 0),
1582 unittest_path(unittest_nr,
1583 PDEV_OVERLAY));
1584 return;
1585 }
1586
1587 /* removing them in order should work */
1588 for (i = 1; i >= 0; i--) {
1589 ovcs_id = ov_id[i];
1590 ret = of_overlay_remove(&ovcs_id);
1591 if (ret != 0) {
1566 unittest_path(unittest_nr,
1567 PDEV_OVERLAY));
1568 return;
1569 }
1570
1571 /* removing them in order should work */
1572 for (i = 1; i >= 0; i--) {
1573 ovcs_id = ov_id[i];
1574 ret = of_overlay_remove(&ovcs_id);
1575 if (ret != 0) {
1592 unittest(0, "overlay @\"%s\" not destroyed @\"%s\"\n",
1593 overlay_path(overlay_nr + i),
1576 unittest(0, "%s not destroyed @\"%s\"\n",
1577 overlay_name_from_nr(overlay_nr + i),
1594 unittest_path(unittest_nr,
1595 PDEV_OVERLAY));
1596 return;
1597 }
1598 of_unittest_untrack_overlay(ov_id[i]);
1599 }
1600
1601 unittest(1, "overlay test %d passed\n", 8);
1602}
1603
1604/* test insertion of a bus with parent devices */
1578 unittest_path(unittest_nr,
1579 PDEV_OVERLAY));
1580 return;
1581 }
1582 of_unittest_untrack_overlay(ov_id[i]);
1583 }
1584
1585 unittest(1, "overlay test %d passed\n", 8);
1586}
1587
1588/* test insertion of a bus with parent devices */
1605static void of_unittest_overlay_10(void)
1589static void __init of_unittest_overlay_10(void)
1606{
1607 int ret;
1608 char *child_path;
1609
1610 /* device should disable */
1611 ret = of_unittest_apply_overlay_check(10, 10, 0, 1, PDEV_OVERLAY);
1612 if (unittest(ret == 0,
1613 "overlay test %d failed; overlay application\n", 10))

--- 6 unchanged lines hidden (view full) ---

1620
1621 ret = of_path_device_type_exists(child_path, PDEV_OVERLAY);
1622 kfree(child_path);
1623 if (unittest(ret, "overlay test %d failed; no child device\n", 10))
1624 return;
1625}
1626
1627/* test insertion of a bus with parent devices (and revert) */
1590{
1591 int ret;
1592 char *child_path;
1593
1594 /* device should disable */
1595 ret = of_unittest_apply_overlay_check(10, 10, 0, 1, PDEV_OVERLAY);
1596 if (unittest(ret == 0,
1597 "overlay test %d failed; overlay application\n", 10))

--- 6 unchanged lines hidden (view full) ---

1604
1605 ret = of_path_device_type_exists(child_path, PDEV_OVERLAY);
1606 kfree(child_path);
1607 if (unittest(ret, "overlay test %d failed; no child device\n", 10))
1608 return;
1609}
1610
1611/* test insertion of a bus with parent devices (and revert) */
1628static void of_unittest_overlay_11(void)
1612static void __init of_unittest_overlay_11(void)
1629{
1630 int ret;
1631
1632 /* device should disable */
1633 ret = of_unittest_apply_revert_overlay_check(11, 11, 0, 1,
1634 PDEV_OVERLAY);
1635 if (unittest(ret == 0,
1636 "overlay test %d failed; overlay application\n", 11))

--- 249 unchanged lines hidden (view full) ---

1886{
1887#if IS_BUILTIN(CONFIG_I2C_MUX)
1888 i2c_del_driver(&unittest_i2c_mux_driver);
1889#endif
1890 platform_driver_unregister(&unittest_i2c_bus_driver);
1891 i2c_del_driver(&unittest_i2c_dev_driver);
1892}
1893
1613{
1614 int ret;
1615
1616 /* device should disable */
1617 ret = of_unittest_apply_revert_overlay_check(11, 11, 0, 1,
1618 PDEV_OVERLAY);
1619 if (unittest(ret == 0,
1620 "overlay test %d failed; overlay application\n", 11))

--- 249 unchanged lines hidden (view full) ---

1870{
1871#if IS_BUILTIN(CONFIG_I2C_MUX)
1872 i2c_del_driver(&unittest_i2c_mux_driver);
1873#endif
1874 platform_driver_unregister(&unittest_i2c_bus_driver);
1875 i2c_del_driver(&unittest_i2c_dev_driver);
1876}
1877
1894static void of_unittest_overlay_i2c_12(void)
1878static void __init of_unittest_overlay_i2c_12(void)
1895{
1896 int ret;
1897
1898 /* device should enable */
1899 ret = of_unittest_apply_overlay_check(12, 12, 0, 1, I2C_OVERLAY);
1900 if (ret != 0)
1901 return;
1902
1903 unittest(1, "overlay test %d passed\n", 12);
1904}
1905
1906/* test deactivation of device */
1879{
1880 int ret;
1881
1882 /* device should enable */
1883 ret = of_unittest_apply_overlay_check(12, 12, 0, 1, I2C_OVERLAY);
1884 if (ret != 0)
1885 return;
1886
1887 unittest(1, "overlay test %d passed\n", 12);
1888}
1889
1890/* test deactivation of device */
1907static void of_unittest_overlay_i2c_13(void)
1891static void __init of_unittest_overlay_i2c_13(void)
1908{
1909 int ret;
1910
1911 /* device should disable */
1912 ret = of_unittest_apply_overlay_check(13, 13, 1, 0, I2C_OVERLAY);
1913 if (ret != 0)
1914 return;
1915
1916 unittest(1, "overlay test %d passed\n", 13);
1917}
1918
1919/* just check for i2c mux existence */
1920static void of_unittest_overlay_i2c_14(void)
1921{
1922}
1923
1892{
1893 int ret;
1894
1895 /* device should disable */
1896 ret = of_unittest_apply_overlay_check(13, 13, 1, 0, I2C_OVERLAY);
1897 if (ret != 0)
1898 return;
1899
1900 unittest(1, "overlay test %d passed\n", 13);
1901}
1902
1903/* just check for i2c mux existence */
1904static void of_unittest_overlay_i2c_14(void)
1905{
1906}
1907
1924static void of_unittest_overlay_i2c_15(void)
1908static void __init of_unittest_overlay_i2c_15(void)
1925{
1926 int ret;
1927
1928 /* device should enable */
1929 ret = of_unittest_apply_overlay_check(15, 15, 0, 1, I2C_OVERLAY);
1930 if (ret != 0)
1931 return;
1932

--- 85 unchanged lines hidden (view full) ---

2018 * __dtb_ot_begin[] and __dtb_ot_end[] are created by cmd_dt_S_dtb
2019 * in scripts/Makefile.lib
2020 */
2021
2022#define OVERLAY_INFO_EXTERN(name) \
2023 extern uint8_t __dtb_##name##_begin[]; \
2024 extern uint8_t __dtb_##name##_end[]
2025
1909{
1910 int ret;
1911
1912 /* device should enable */
1913 ret = of_unittest_apply_overlay_check(15, 15, 0, 1, I2C_OVERLAY);
1914 if (ret != 0)
1915 return;
1916

--- 85 unchanged lines hidden (view full) ---

2002 * __dtb_ot_begin[] and __dtb_ot_end[] are created by cmd_dt_S_dtb
2003 * in scripts/Makefile.lib
2004 */
2005
2006#define OVERLAY_INFO_EXTERN(name) \
2007 extern uint8_t __dtb_##name##_begin[]; \
2008 extern uint8_t __dtb_##name##_end[]
2009
2026#define OVERLAY_INFO(name, expected) \
2027{ .dtb_begin = __dtb_##name##_begin, \
2028 .dtb_end = __dtb_##name##_end, \
2029 .expected_result = expected, \
2010#define OVERLAY_INFO(overlay_name, expected) \
2011{ .dtb_begin = __dtb_##overlay_name##_begin, \
2012 .dtb_end = __dtb_##overlay_name##_end, \
2013 .expected_result = expected, \
2014 .name = #overlay_name, \
2030}
2031
2032struct overlay_info {
2015}
2016
2017struct overlay_info {
2033 uint8_t *dtb_begin;
2034 uint8_t *dtb_end;
2035 void *data;
2036 struct device_node *np_overlay;
2037 int expected_result;
2038 int overlay_id;
2018 uint8_t *dtb_begin;
2019 uint8_t *dtb_end;
2020 int expected_result;
2021 int overlay_id;
2022 char *name;
2039};
2040
2041OVERLAY_INFO_EXTERN(overlay_base);
2042OVERLAY_INFO_EXTERN(overlay);
2023};
2024
2025OVERLAY_INFO_EXTERN(overlay_base);
2026OVERLAY_INFO_EXTERN(overlay);
2027OVERLAY_INFO_EXTERN(overlay_0);
2028OVERLAY_INFO_EXTERN(overlay_1);
2029OVERLAY_INFO_EXTERN(overlay_2);
2030OVERLAY_INFO_EXTERN(overlay_3);
2031OVERLAY_INFO_EXTERN(overlay_4);
2032OVERLAY_INFO_EXTERN(overlay_5);
2033OVERLAY_INFO_EXTERN(overlay_6);
2034OVERLAY_INFO_EXTERN(overlay_7);
2035OVERLAY_INFO_EXTERN(overlay_8);
2036OVERLAY_INFO_EXTERN(overlay_9);
2037OVERLAY_INFO_EXTERN(overlay_10);
2038OVERLAY_INFO_EXTERN(overlay_11);
2039OVERLAY_INFO_EXTERN(overlay_12);
2040OVERLAY_INFO_EXTERN(overlay_13);
2041OVERLAY_INFO_EXTERN(overlay_15);
2043OVERLAY_INFO_EXTERN(overlay_bad_phandle);
2044OVERLAY_INFO_EXTERN(overlay_bad_symbol);
2045
2046/* order of entries is hard-coded into users of overlays[] */
2047static struct overlay_info overlays[] = {
2048 OVERLAY_INFO(overlay_base, -9999),
2049 OVERLAY_INFO(overlay, 0),
2042OVERLAY_INFO_EXTERN(overlay_bad_phandle);
2043OVERLAY_INFO_EXTERN(overlay_bad_symbol);
2044
2045/* order of entries is hard-coded into users of overlays[] */
2046static struct overlay_info overlays[] = {
2047 OVERLAY_INFO(overlay_base, -9999),
2048 OVERLAY_INFO(overlay, 0),
2049 OVERLAY_INFO(overlay_0, 0),
2050 OVERLAY_INFO(overlay_1, 0),
2051 OVERLAY_INFO(overlay_2, 0),
2052 OVERLAY_INFO(overlay_3, 0),
2053 OVERLAY_INFO(overlay_4, 0),
2054 OVERLAY_INFO(overlay_5, 0),
2055 OVERLAY_INFO(overlay_6, 0),
2056 OVERLAY_INFO(overlay_7, 0),
2057 OVERLAY_INFO(overlay_8, 0),
2058 OVERLAY_INFO(overlay_9, 0),
2059 OVERLAY_INFO(overlay_10, 0),
2060 OVERLAY_INFO(overlay_11, 0),
2061 OVERLAY_INFO(overlay_12, 0),
2062 OVERLAY_INFO(overlay_13, 0),
2063 OVERLAY_INFO(overlay_15, 0),
2050 OVERLAY_INFO(overlay_bad_phandle, -EINVAL),
2051 OVERLAY_INFO(overlay_bad_symbol, -EINVAL),
2052 {}
2053};
2054
2055static struct device_node *overlay_base_root;
2056
2057static void * __init dt_alloc_memory(u64 size, u64 align)

--- 14 unchanged lines hidden (view full) ---

2072 * code" as little as possible.
2073 *
2074 * Have to stop before resolving phandles, because that uses kmalloc.
2075 */
2076void __init unittest_unflatten_overlay_base(void)
2077{
2078 struct overlay_info *info;
2079 u32 data_size;
2064 OVERLAY_INFO(overlay_bad_phandle, -EINVAL),
2065 OVERLAY_INFO(overlay_bad_symbol, -EINVAL),
2066 {}
2067};
2068
2069static struct device_node *overlay_base_root;
2070
2071static void * __init dt_alloc_memory(u64 size, u64 align)

--- 14 unchanged lines hidden (view full) ---

2086 * code" as little as possible.
2087 *
2088 * Have to stop before resolving phandles, because that uses kmalloc.
2089 */
2090void __init unittest_unflatten_overlay_base(void)
2091{
2092 struct overlay_info *info;
2093 u32 data_size;
2094 void *new_fdt;
2080 u32 size;
2081
2082 info = &overlays[0];
2083
2084 if (info->expected_result != -9999) {
2085 pr_err("No dtb 'overlay_base' to attach\n");
2086 return;
2087 }

--- 5 unchanged lines hidden (view full) ---

2093 }
2094
2095 size = fdt_totalsize(info->dtb_begin);
2096 if (size != data_size) {
2097 pr_err("dtb 'overlay_base' header totalsize != actual size");
2098 return;
2099 }
2100
2095 u32 size;
2096
2097 info = &overlays[0];
2098
2099 if (info->expected_result != -9999) {
2100 pr_err("No dtb 'overlay_base' to attach\n");
2101 return;
2102 }

--- 5 unchanged lines hidden (view full) ---

2108 }
2109
2110 size = fdt_totalsize(info->dtb_begin);
2111 if (size != data_size) {
2112 pr_err("dtb 'overlay_base' header totalsize != actual size");
2113 return;
2114 }
2115
2101 info->data = dt_alloc_memory(size, roundup_pow_of_two(FDT_V17_SIZE));
2102 if (!info->data) {
2116 new_fdt = dt_alloc_memory(size, roundup_pow_of_two(FDT_V17_SIZE));
2117 if (!new_fdt) {
2103 pr_err("alloc for dtb 'overlay_base' failed");
2104 return;
2105 }
2106
2118 pr_err("alloc for dtb 'overlay_base' failed");
2119 return;
2120 }
2121
2107 memcpy(info->data, info->dtb_begin, size);
2122 memcpy(new_fdt, info->dtb_begin, size);
2108
2123
2109 __unflatten_device_tree(info->data, NULL, &info->np_overlay,
2124 __unflatten_device_tree(new_fdt, NULL, &overlay_base_root,
2110 dt_alloc_memory, true);
2125 dt_alloc_memory, true);
2111 overlay_base_root = info->np_overlay;
2112}
2113
2114/*
2115 * The purpose of of_unittest_overlay_data_add is to add an
2116 * overlay in the normal fashion. This is a test of the whole
2117 * picture, instead of testing individual elements.
2118 *
2119 * A secondary purpose is to be able to verify that the contents of
2120 * /proc/device-tree/ contains the updated structure and values from
2121 * the overlay. That must be verified separately in user space.
2122 *
2123 * Return 0 on unexpected error.
2124 */
2126}
2127
2128/*
2129 * The purpose of of_unittest_overlay_data_add is to add an
2130 * overlay in the normal fashion. This is a test of the whole
2131 * picture, instead of testing individual elements.
2132 *
2133 * A secondary purpose is to be able to verify that the contents of
2134 * /proc/device-tree/ contains the updated structure and values from
2135 * the overlay. That must be verified separately in user space.
2136 *
2137 * Return 0 on unexpected error.
2138 */
2125static int __init overlay_data_add(int onum)
2139static int __init overlay_data_apply(const char *overlay_name, int *overlay_id)
2126{
2127 struct overlay_info *info;
2140{
2141 struct overlay_info *info;
2142 int found = 0;
2128 int k;
2129 int ret;
2130 u32 size;
2143 int k;
2144 int ret;
2145 u32 size;
2131 u32 size_from_header;
2132
2146
2133 for (k = 0, info = overlays; info; info++, k++) {
2134 if (k == onum)
2147 for (k = 0, info = overlays; info && info->name; info++, k++) {
2148 if (!strcmp(overlay_name, info->name)) {
2149 found = 1;
2135 break;
2150 break;
2151 }
2136 }
2152 }
2137 if (onum > k)
2153 if (!found) {
2154 pr_err("no overlay data for %s\n", overlay_name);
2138 return 0;
2155 return 0;
2156 }
2139
2140 size = info->dtb_end - info->dtb_begin;
2141 if (!size) {
2157
2158 size = info->dtb_end - info->dtb_begin;
2159 if (!size) {
2142 pr_err("no overlay to attach, %d\n", onum);
2160 pr_err("no overlay data for %s\n", overlay_name);
2143 ret = 0;
2144 }
2145
2161 ret = 0;
2162 }
2163
2146 size_from_header = fdt_totalsize(info->dtb_begin);
2147 if (size_from_header != size) {
2148 pr_err("overlay header totalsize != actual size, %d", onum);
2149 return 0;
2150 }
2164 ret = of_overlay_fdt_apply(info->dtb_begin, size, &info->overlay_id);
2165 if (overlay_id)
2166 *overlay_id = info->overlay_id;
2167 if (ret < 0)
2168 goto out;
2151
2169
2152 /*
2153 * Must create permanent copy of FDT because of_fdt_unflatten_tree()
2154 * will create pointers to the passed in FDT in the EDT.
2155 */
2156 info->data = kmemdup(info->dtb_begin, size, GFP_KERNEL);
2157 if (!info->data) {
2158 pr_err("unable to allocate memory for data, %d\n", onum);
2159 return 0;
2160 }
2170 pr_debug("%s applied\n", overlay_name);
2161
2171
2162 of_fdt_unflatten_tree(info->data, NULL, &info->np_overlay);
2163 if (!info->np_overlay) {
2164 pr_err("unable to unflatten overlay, %d\n", onum);
2165 ret = 0;
2166 goto out_free_data;
2167 }
2168
2169 info->overlay_id = 0;
2170 ret = of_overlay_apply(info->np_overlay, &info->overlay_id);
2171 if (ret < 0) {
2172 pr_err("of_overlay_apply() (ret=%d), %d\n", ret, onum);
2173 goto out_free_np_overlay;
2174 }
2175
2176 pr_debug("__dtb_overlay_begin applied, overlay id %d\n", ret);
2177
2178 goto out;
2179
2180out_free_np_overlay:
2181 /*
2182 * info->np_overlay is the unflattened device tree
2183 * It has not been spliced into the live tree.
2184 */
2185
2186 /* todo: function to free unflattened device tree */
2187
2188out_free_data:
2189 kfree(info->data);
2190
2191out:
2172out:
2173 if (ret != info->expected_result)
2174 pr_err("of_overlay_fdt_apply() expected %d, ret=%d, %s\n",
2175 info->expected_result, ret, overlay_name);
2176
2192 return (ret == info->expected_result);
2193}
2194
2195/*
2196 * The purpose of of_unittest_overlay_high_level is to add an overlay
2197 * in the normal fashion. This is a test of the whole picture,
2198 * instead of individual elements.
2199 *

--- 85 unchanged lines hidden (view full) ---

2285 last_sibling->sibling = overlay_base_root->child;
2286 else
2287 of_root->child = overlay_base_root->child;
2288
2289 for_each_of_allnodes_from(overlay_base_root, np)
2290 __of_attach_node_sysfs(np);
2291
2292 if (of_symbols) {
2177 return (ret == info->expected_result);
2178}
2179
2180/*
2181 * The purpose of of_unittest_overlay_high_level is to add an overlay
2182 * in the normal fashion. This is a test of the whole picture,
2183 * instead of individual elements.
2184 *

--- 85 unchanged lines hidden (view full) ---

2270 last_sibling->sibling = overlay_base_root->child;
2271 else
2272 of_root->child = overlay_base_root->child;
2273
2274 for_each_of_allnodes_from(overlay_base_root, np)
2275 __of_attach_node_sysfs(np);
2276
2277 if (of_symbols) {
2278 struct property *new_prop;
2293 for_each_property_of_node(overlay_base_symbols, prop) {
2279 for_each_property_of_node(overlay_base_symbols, prop) {
2294 ret = __of_add_property(of_symbols, prop);
2280
2281 new_prop = __of_prop_dup(prop, GFP_KERNEL);
2282 if (!new_prop) {
2283 unittest(0, "__of_prop_dup() of '%s' from overlay_base node __symbols__",
2284 prop->name);
2285 goto err_unlock;
2286 }
2287 ret = __of_add_property(of_symbols, new_prop);
2295 if (ret) {
2288 if (ret) {
2296 unittest(0,
2297 "duplicate property '%s' in overlay_base node __symbols__",
2289 if (!strcmp(new_prop->name, "name")) {
2290 /* auto-generated by unflatten */
2291 ret = 0;
2292 continue;
2293 }
2294 unittest(0, "duplicate property '%s' in overlay_base node __symbols__",
2298 prop->name);
2299 goto err_unlock;
2300 }
2295 prop->name);
2296 goto err_unlock;
2297 }
2301 ret = __of_add_property_sysfs(of_symbols, prop);
2298 ret = __of_add_property_sysfs(of_symbols, new_prop);
2302 if (ret) {
2299 if (ret) {
2303 unittest(0,
2304 "unable to add property '%s' in overlay_base node __symbols__ to sysfs",
2300 unittest(0, "unable to add property '%s' in overlay_base node __symbols__ to sysfs",
2305 prop->name);
2306 goto err_unlock;
2307 }
2308 }
2309 }
2310
2311 mutex_unlock(&of_mutex);
2312
2313
2314 /* now do the normal overlay usage test */
2315
2301 prop->name);
2302 goto err_unlock;
2303 }
2304 }
2305 }
2306
2307 mutex_unlock(&of_mutex);
2308
2309
2310 /* now do the normal overlay usage test */
2311
2316 unittest(overlay_data_add(1),
2312 unittest(overlay_data_apply("overlay", NULL),
2317 "Adding overlay 'overlay' failed\n");
2318
2313 "Adding overlay 'overlay' failed\n");
2314
2319 unittest(overlay_data_add(2),
2315 unittest(overlay_data_apply("overlay_bad_phandle", NULL),
2320 "Adding overlay 'overlay_bad_phandle' failed\n");
2321
2316 "Adding overlay 'overlay_bad_phandle' failed\n");
2317
2322 unittest(overlay_data_add(3),
2318 unittest(overlay_data_apply("overlay_bad_symbol", NULL),
2323 "Adding overlay 'overlay_bad_symbol' failed\n");
2324
2325 return;
2326
2327err_unlock:
2328 mutex_unlock(&of_mutex);
2329}
2330

--- 52 unchanged lines hidden ---
2319 "Adding overlay 'overlay_bad_symbol' failed\n");
2320
2321 return;
2322
2323err_unlock:
2324 mutex_unlock(&of_mutex);
2325}
2326

--- 52 unchanged lines hidden ---