diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-15 03:25:40 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-11-15 03:25:40 +0100 |
commit | 37cb8e1f8e10c6e9bd2a1b95cdda0620a21b0551 (patch) | |
tree | a1302a6cd2978d7a089534b8232ef3bfa921610e /drivers/of/unittest.c | |
parent | Merge tag 'leds_for_4.15rc1' of git://git.kernel.org/pub/scm/linux/kernel/git... (diff) | |
parent | dt-bindings: usb: add #phy-cells to usb-nop-xceiv (diff) | |
download | linux-37cb8e1f8e10c6e9bd2a1b95cdda0620a21b0551.tar.xz linux-37cb8e1f8e10c6e9bd2a1b95cdda0620a21b0551.zip |
Merge tag 'devicetree-for-4.15' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux
Pull DeviceTree updates from Rob Herring:
"A bigger diffstat than usual with the kbuild changes and a tree wide
fix in the binding documentation.
Summary:
- kbuild cleanups and improvements for dtbs
- Code clean-up of overlay code and fixing for some long standing
memory leak and race condition in applying overlays
- Improvements to DT memory usage making sysfs/kobjects optional and
skipping unflattening of disabled nodes. This is part of kernel
tinification efforts.
- Final piece of removing storing the full path for every DT node.
The prerequisite conversion of printk's to use device_node format
specifier happened in 4.14.
- Sync with current upstream dtc. This brings additional checks to
dtb compiling.
- Binding doc tree wide removal of leading 0s from examples
- RTC binding documentation adding missing devices and some
consolidation of duplicated bindings
- Vendor prefix documentation for nutsboard, Silicon Storage
Technology, shimafuji, Tecon Microprocessor Technologies, DH
electronics GmbH, Opal Kelly, and Next Thing"
* tag 'devicetree-for-4.15' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux: (55 commits)
dt-bindings: usb: add #phy-cells to usb-nop-xceiv
dt-bindings: Remove leading zeros from bindings notation
kbuild: handle dtb-y and CONFIG_OF_ALL_DTBS natively in Makefile.lib
MIPS: dts: remove bogus bcm96358nb4ser.dtb from dtb-y entry
kbuild: clean up *.dtb and *.dtb.S patterns from top-level Makefile
.gitignore: move *.dtb and *.dtb.S patterns to the top-level .gitignore
.gitignore: sort normal pattern rules alphabetically
dt-bindings: add vendor prefix for Next Thing Co.
scripts/dtc: Update to upstream version v1.4.5-6-gc1e55a5513e9
of: dynamic: fix memory leak related to properties of __of_node_dup
of: overlay: make pr_err() string unique
of: overlay: pr_err from return NOTIFY_OK to overlay apply/remove
of: overlay: remove unneeded check for NULL kbasename()
of: overlay: remove a dependency on device node full_name
of: overlay: simplify applying symbols from an overlay
of: overlay: avoid race condition between applying multiple overlays
of: overlay: loosen overly strict phandle clash check
of: overlay: expand check of whether overlay changeset can be removed
of: overlay: detect cases where device tree may become corrupt
of: overlay: minor restructuring
...
Diffstat (limited to 'drivers/of/unittest.c')
-rw-r--r-- | drivers/of/unittest.c | 83 |
1 files changed, 47 insertions, 36 deletions
diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 168ef0bbabde..e568b1e82501 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -994,10 +994,17 @@ static int __init unittest_data_add(void) pr_warn("%s: No tree to attach; not running tests\n", __func__); return -ENODATA; } - of_node_set_flag(unittest_data_node, OF_DETACHED); + + /* + * This lock normally encloses of_overlay_apply() as well as + * of_resolve_phandles(). + */ + of_overlay_mutex_lock(); + rc = of_resolve_phandles(unittest_data_node); if (rc) { pr_err("%s: Failed to resolve phandles (rc=%i)\n", __func__, rc); + of_overlay_mutex_unlock(); return -EINVAL; } @@ -1007,6 +1014,7 @@ static int __init unittest_data_add(void) __of_attach_node_sysfs(np); of_aliases = of_find_node_by_path("/aliases"); of_chosen = of_find_node_by_path("/chosen"); + of_overlay_mutex_unlock(); return 0; } @@ -1019,6 +1027,9 @@ static int __init unittest_data_add(void) attach_node_and_children(np); np = next; } + + of_overlay_mutex_unlock(); + return 0; } @@ -1219,7 +1230,7 @@ static void of_unittest_untrack_overlay(int id) static void of_unittest_destroy_tracked_overlays(void) { - int id, ret, defers; + int id, ret, defers, ovcs_id; if (overlay_first_id < 0) return; @@ -1232,7 +1243,8 @@ static void of_unittest_destroy_tracked_overlays(void) if (!(overlay_id_bits[BIT_WORD(id)] & BIT_MASK(id))) continue; - ret = of_overlay_destroy(id + overlay_first_id); + ovcs_id = id + overlay_first_id; + ret = of_overlay_remove(&ovcs_id); if (ret == -ENODEV) { pr_warn("%s: no overlay to destroy for #%d\n", __func__, id + overlay_first_id); @@ -1254,7 +1266,7 @@ static int of_unittest_apply_overlay(int overlay_nr, int unittest_nr, int *overlay_id) { struct device_node *np = NULL; - int ret, id = -1; + int ret; np = of_find_node_by_path(overlay_path(overlay_nr)); if (np == NULL) { @@ -1264,23 +1276,20 @@ static int of_unittest_apply_overlay(int overlay_nr, int unittest_nr, goto out; } - ret = of_overlay_create(np); + *overlay_id = 0; + ret = of_overlay_apply(np, overlay_id); if (ret < 0) { unittest(0, "could not create overlay from \"%s\"\n", overlay_path(overlay_nr)); goto out; } - id = ret; - of_unittest_track_overlay(id); + of_unittest_track_overlay(*overlay_id); ret = 0; out: of_node_put(np); - if (overlay_id) - *overlay_id = id; - return ret; } @@ -1288,7 +1297,7 @@ out: static int of_unittest_apply_overlay_check(int overlay_nr, int unittest_nr, int before, int after, enum overlay_type ovtype) { - int ret; + int ret, ovcs_id; /* unittest device must not be in before state */ if (of_unittest_device_exists(unittest_nr, ovtype) != before) { @@ -1299,7 +1308,8 @@ static int of_unittest_apply_overlay_check(int overlay_nr, int unittest_nr, return -EINVAL; } - ret = of_unittest_apply_overlay(overlay_nr, unittest_nr, NULL); + ovcs_id = 0; + ret = of_unittest_apply_overlay(overlay_nr, unittest_nr, &ovcs_id); if (ret != 0) { /* of_unittest_apply_overlay already called unittest() */ return ret; @@ -1322,7 +1332,7 @@ static int of_unittest_apply_revert_overlay_check(int overlay_nr, int unittest_nr, int before, int after, enum overlay_type ovtype) { - int ret, ov_id; + int ret, ovcs_id; /* unittest device must be in before state */ if (of_unittest_device_exists(unittest_nr, ovtype) != before) { @@ -1334,7 +1344,8 @@ static int of_unittest_apply_revert_overlay_check(int overlay_nr, } /* apply the overlay */ - ret = of_unittest_apply_overlay(overlay_nr, unittest_nr, &ov_id); + ovcs_id = 0; + ret = of_unittest_apply_overlay(overlay_nr, unittest_nr, &ovcs_id); if (ret != 0) { /* of_unittest_apply_overlay already called unittest() */ return ret; @@ -1349,7 +1360,7 @@ static int of_unittest_apply_revert_overlay_check(int overlay_nr, return -EINVAL; } - ret = of_overlay_destroy(ov_id); + ret = of_overlay_remove(&ovcs_id); if (ret != 0) { unittest(0, "overlay @\"%s\" failed to be destroyed @\"%s\"\n", overlay_path(overlay_nr), @@ -1451,7 +1462,7 @@ static void of_unittest_overlay_5(void) static void of_unittest_overlay_6(void) { struct device_node *np; - int ret, i, ov_id[2]; + int ret, i, ov_id[2], ovcs_id; int overlay_nr = 6, unittest_nr = 6; int before = 0, after = 1; @@ -1478,13 +1489,14 @@ static void of_unittest_overlay_6(void) return; } - ret = of_overlay_create(np); + ovcs_id = 0; + ret = of_overlay_apply(np, &ovcs_id); if (ret < 0) { unittest(0, "could not create overlay from \"%s\"\n", overlay_path(overlay_nr + i)); return; } - ov_id[i] = ret; + ov_id[i] = ovcs_id; of_unittest_track_overlay(ov_id[i]); } @@ -1502,7 +1514,8 @@ static void of_unittest_overlay_6(void) } for (i = 1; i >= 0; i--) { - ret = of_overlay_destroy(ov_id[i]); + ovcs_id = ov_id[i]; + ret = of_overlay_remove(&ovcs_id); if (ret != 0) { unittest(0, "overlay @\"%s\" failed destroy @\"%s\"\n", overlay_path(overlay_nr + i), @@ -1533,7 +1546,7 @@ static void of_unittest_overlay_6(void) static void of_unittest_overlay_8(void) { struct device_node *np; - int ret, i, ov_id[2]; + int ret, i, ov_id[2], ovcs_id; int overlay_nr = 8, unittest_nr = 8; /* we don't care about device state in this test */ @@ -1548,18 +1561,20 @@ static void of_unittest_overlay_8(void) return; } - ret = of_overlay_create(np); + ovcs_id = 0; + ret = of_overlay_apply(np, &ovcs_id); if (ret < 0) { unittest(0, "could not create overlay from \"%s\"\n", overlay_path(overlay_nr + i)); return; } - ov_id[i] = ret; + ov_id[i] = ovcs_id; of_unittest_track_overlay(ov_id[i]); } /* now try to remove first overlay (it should fail) */ - ret = of_overlay_destroy(ov_id[0]); + ovcs_id = ov_id[0]; + ret = of_overlay_remove(&ovcs_id); if (ret == 0) { unittest(0, "overlay @\"%s\" was destroyed @\"%s\"\n", overlay_path(overlay_nr + 0), @@ -1570,7 +1585,8 @@ static void of_unittest_overlay_8(void) /* removing them in order should work */ for (i = 1; i >= 0; i--) { - ret = of_overlay_destroy(ov_id[i]); + ovcs_id = ov_id[i]; + ret = of_overlay_remove(&ovcs_id); if (ret != 0) { unittest(0, "overlay @\"%s\" not destroyed @\"%s\"\n", overlay_path(overlay_nr + i), @@ -2144,21 +2160,13 @@ static int __init overlay_data_add(int onum) ret = 0; goto out_free_data; } - of_node_set_flag(info->np_overlay, OF_DETACHED); - ret = of_resolve_phandles(info->np_overlay); - if (ret) { - pr_err("resolve ot phandles (ret=%d), %d\n", ret, onum); - goto out_free_np_overlay; - } - - ret = of_overlay_create(info->np_overlay); + info->overlay_id = 0; + ret = of_overlay_apply(info->np_overlay, &info->overlay_id); if (ret < 0) { - pr_err("of_overlay_create() (ret=%d), %d\n", ret, onum); + pr_err("of_overlay_apply() (ret=%d), %d\n", ret, onum); + of_overlay_mutex_unlock(); goto out_free_np_overlay; - } else { - info->overlay_id = ret; - ret = 0; } pr_debug("__dtb_overlay_begin applied, overlay id %d\n", ret); @@ -2207,7 +2215,10 @@ static __init void of_unittest_overlay_high_level(void) * Could not fixup phandles in unittest_unflatten_overlay_base() * because kmalloc() was not yet available. */ + of_overlay_mutex_lock(); of_resolve_phandles(overlay_base_root); + of_overlay_mutex_unlock(); + /* * do not allow overlay_base to duplicate any node already in |