diff options
author | Thomas Hellström <thomas.hellstrom@linux.intel.com> | 2024-10-04 11:29:21 +0200 |
---|---|---|
committer | Thomas Hellström <thomas.hellstrom@linux.intel.com> | 2024-10-04 11:46:30 +0200 |
commit | b88132ceb3faccdd785809df75f9d490ebaab459 (patch) | |
tree | ea383d842f8b5fc4f72ca1ebbd6c02a99754071b /drivers/of | |
parent | 491418a258322bbd7f045e36884d2849b673f23d (diff) | |
parent | 9852d85ec9d492ebef56dc5f229416c925758edc (diff) |
Merge drm/drm-next into drm-xe-next
Backmerging to resolve a conflict with core locally.
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Diffstat (limited to 'drivers/of')
-rw-r--r-- | drivers/of/.kunitconfig | 1 | ||||
-rw-r--r-- | drivers/of/Kconfig | 10 | ||||
-rw-r--r-- | drivers/of/Makefile | 3 | ||||
-rw-r--r-- | drivers/of/address.c | 40 | ||||
-rw-r--r-- | drivers/of/fdt.c | 2 | ||||
-rw-r--r-- | drivers/of/irq.c | 43 | ||||
-rw-r--r-- | drivers/of/kunit_overlay_test.dtso | 9 | ||||
-rw-r--r-- | drivers/of/of_kunit_helpers.c | 77 | ||||
-rw-r--r-- | drivers/of/of_numa.c | 5 | ||||
-rw-r--r-- | drivers/of/overlay.c | 12 | ||||
-rw-r--r-- | drivers/of/overlay_test.c | 115 | ||||
-rw-r--r-- | drivers/of/platform.c | 23 | ||||
-rw-r--r-- | drivers/of/property.c | 41 | ||||
-rw-r--r-- | drivers/of/resolver.c | 12 | ||||
-rw-r--r-- | drivers/of/unittest.c | 8 |
15 files changed, 293 insertions, 108 deletions
diff --git a/drivers/of/.kunitconfig b/drivers/of/.kunitconfig index 5a8fee11978c..4c53d2c7a275 100644 --- a/drivers/of/.kunitconfig +++ b/drivers/of/.kunitconfig @@ -1,3 +1,4 @@ CONFIG_KUNIT=y CONFIG_OF=y CONFIG_OF_KUNIT_TEST=y +CONFIG_OF_OVERLAY_KUNIT_TEST=y diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index dd726c7056bf..0e2d608c3e20 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig @@ -107,6 +107,16 @@ config OF_OVERLAY While this option is selected automatically when needed, you can enable it manually to improve device tree unit test coverage. +config OF_OVERLAY_KUNIT_TEST + tristate "Device Tree overlay KUnit tests" if !KUNIT_ALL_TESTS + depends on KUNIT + default KUNIT_ALL_TESTS + select OF_OVERLAY + help + This option builds KUnit unit tests for the device tree overlay code. + + If unsure, say N here, but this option is safe to enable. + config OF_NUMA bool diff --git a/drivers/of/Makefile b/drivers/of/Makefile index 251d33532148..379a0afcbdc0 100644 --- a/drivers/of/Makefile +++ b/drivers/of/Makefile @@ -19,6 +19,9 @@ obj-y += kexec.o endif endif +obj-$(CONFIG_KUNIT) += of_kunit_helpers.o obj-$(CONFIG_OF_KUNIT_TEST) += of_test.o +obj-$(CONFIG_OF_OVERLAY_KUNIT_TEST) += overlay-test.o +overlay-test-y := overlay_test.o kunit_overlay_test.dtbo.o obj-$(CONFIG_OF_UNITTEST) += unittest-data/ diff --git a/drivers/of/address.c b/drivers/of/address.c index d669ce25b5f9..286f0c161e33 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -8,6 +8,7 @@ #include <linux/logic_pio.h> #include <linux/module.h> #include <linux/of_address.h> +#include <linux/overflow.h> #include <linux/pci.h> #include <linux/pci_regs.h> #include <linux/sizes.h> @@ -197,6 +198,23 @@ static u64 of_bus_pci_map(__be32 *addr, const __be32 *range, int na, int ns, #endif /* CONFIG_PCI */ +static int __of_address_resource_bounds(struct resource *r, u64 start, u64 size) +{ + u64 end = start; + + if (overflows_type(start, r->start)) + return -EOVERFLOW; + if (size && check_add_overflow(end, size - 1, &end)) + return -EOVERFLOW; + if (overflows_type(end, r->end)) + return -EOVERFLOW; + + r->start = start; + r->end = end; + + return 0; +} + /* * of_pci_range_to_resource - Create a resource from an of_pci_range * @range: the PCI range that describes the resource @@ -215,6 +233,7 @@ static u64 of_bus_pci_map(__be32 *addr, const __be32 *range, int na, int ns, int of_pci_range_to_resource(struct of_pci_range *range, struct device_node *np, struct resource *res) { + u64 start; int err; res->flags = range->flags; res->parent = res->child = res->sibling = NULL; @@ -231,18 +250,11 @@ int of_pci_range_to_resource(struct of_pci_range *range, err = -EINVAL; goto invalid_range; } - res->start = port; + start = port; } else { - if ((sizeof(resource_size_t) < 8) && - upper_32_bits(range->cpu_addr)) { - err = -EINVAL; - goto invalid_range; - } - - res->start = range->cpu_addr; + start = range->cpu_addr; } - res->end = res->start + range->size - 1; - return 0; + return __of_address_resource_bounds(res, start, range->size); invalid_range: res->start = (resource_size_t)OF_BAD_ADDR; @@ -258,8 +270,8 @@ EXPORT_SYMBOL(of_pci_range_to_resource); * @res: pointer to a valid resource that will be updated to * reflect the values contained in the range. * - * Returns ENOENT if the entry is not found or EINVAL if the range cannot be - * converted to resource. + * Returns -ENOENT if the entry is not found or -EOVERFLOW if the range + * cannot be converted to resource. */ int of_range_to_resource(struct device_node *np, int index, struct resource *res) { @@ -1061,12 +1073,10 @@ static int __of_address_to_resource(struct device_node *dev, int index, int bar_ if (of_mmio_is_nonposted(dev)) flags |= IORESOURCE_MEM_NONPOSTED; - r->start = taddr; - r->end = taddr + size - 1; r->flags = flags; r->name = name ? name : dev->full_name; - return 0; + return __of_address_resource_bounds(r, taddr, size); } /** diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 68103ad230ee..4d528c10df3a 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -34,7 +34,7 @@ /* * __dtb_empty_root_begin[] and __dtb_empty_root_end[] magically created by - * cmd_dt_S_dtb in scripts/Makefile.lib + * cmd_wrap_S_dtb in scripts/Makefile.dtbs */ extern uint8_t __dtb_empty_root_begin[]; extern uint8_t __dtb_empty_root_end[]; diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 8fd63100ba8f..a494f56a0d0e 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c @@ -357,8 +357,8 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_ar addr = of_get_property(device, "reg", &addr_len); /* Prevent out-of-bounds read in case of longer interrupt parent address size */ - if (addr_len > (3 * sizeof(__be32))) - addr_len = 3 * sizeof(__be32); + if (addr_len > sizeof(addr_buf)) + addr_len = sizeof(addr_buf); if (addr) memcpy(addr_buf, addr, addr_len); @@ -429,9 +429,8 @@ int of_irq_to_resource(struct device_node *dev, int index, struct resource *r) of_property_read_string_index(dev, "interrupt-names", index, &name); - r->start = r->end = irq; - r->flags = IORESOURCE_IRQ | irqd_get_trigger_type(irq_get_irq_data(irq)); - r->name = name ? name : of_node_full_name(dev); + *r = DEFINE_RES_IRQ_NAMED(irq, name ?: of_node_full_name(dev)); + r->flags |= irq_get_trigger_type(irq); } return irq; @@ -716,8 +715,7 @@ struct irq_domain *of_msi_map_get_device_domain(struct device *dev, u32 id, * @np: device node for @dev * @token: bus type for this domain * - * Parse the msi-parent property (both the simple and the complex - * versions), and returns the corresponding MSI domain. + * Parse the msi-parent property and returns the corresponding MSI domain. * * Returns: the MSI domain for this device (or NULL on failure). */ @@ -725,33 +723,14 @@ struct irq_domain *of_msi_get_domain(struct device *dev, struct device_node *np, enum irq_domain_bus_token token) { - struct device_node *msi_np; + struct of_phandle_iterator it; struct irq_domain *d; + int err; - /* Check for a single msi-parent property */ - msi_np = of_parse_phandle(np, "msi-parent", 0); - if (msi_np && !of_property_read_bool(msi_np, "#msi-cells")) { - d = irq_find_matching_host(msi_np, token); - if (!d) - of_node_put(msi_np); - return d; - } - - if (token == DOMAIN_BUS_PLATFORM_MSI) { - /* Check for the complex msi-parent version */ - struct of_phandle_args args; - int index = 0; - - while (!of_parse_phandle_with_args(np, "msi-parent", - "#msi-cells", - index, &args)) { - d = irq_find_matching_host(args.np, token); - if (d) - return d; - - of_node_put(args.np); - index++; - } + of_for_each_phandle(&it, err, np, "msi-parent", "#msi-cells", 0) { + d = irq_find_matching_host(it.node, token); + if (d) + return d; } return NULL; diff --git a/drivers/of/kunit_overlay_test.dtso b/drivers/of/kunit_overlay_test.dtso new file mode 100644 index 000000000000..85f20b4b4c16 --- /dev/null +++ b/drivers/of/kunit_overlay_test.dtso @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/plugin/; + +&{/} { + kunit-test { + compatible = "test,empty"; + }; +}; diff --git a/drivers/of/of_kunit_helpers.c b/drivers/of/of_kunit_helpers.c new file mode 100644 index 000000000000..287d6c91bb37 --- /dev/null +++ b/drivers/of/of_kunit_helpers.c @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Test managed DeviceTree APIs + */ + +#include <linux/of.h> +#include <linux/of_fdt.h> + +#include <kunit/of.h> +#include <kunit/test.h> +#include <kunit/resource.h> + +#if defined(CONFIG_OF_OVERLAY) && defined(CONFIG_OF_EARLY_FLATTREE) + +static void of_overlay_fdt_apply_kunit_exit(void *ovcs_id) +{ + of_overlay_remove(ovcs_id); +} + +/** + * of_overlay_fdt_apply_kunit() - Test managed of_overlay_fdt_apply() + * @test: test context + * @overlay_fdt: device tree overlay to apply + * @overlay_fdt_size: size in bytes of @overlay_fdt + * @ovcs_id: identifier of overlay, used to remove the overlay + * + * Just like of_overlay_fdt_apply(), except the overlay is managed by the test + * case and is automatically removed with of_overlay_remove() after the test + * case concludes. + * + * Return: 0 on success, negative errno on failure + */ +int of_overlay_fdt_apply_kunit(struct kunit *test, void *overlay_fdt, + u32 overlay_fdt_size, int *ovcs_id) +{ + int ret; + int *copy_id; + + copy_id = kunit_kmalloc(test, sizeof(*copy_id), GFP_KERNEL); + if (!copy_id) + return -ENOMEM; + + ret = of_overlay_fdt_apply(overlay_fdt, overlay_fdt_size, + ovcs_id, NULL); + if (ret) + return ret; + + *copy_id = *ovcs_id; + + return kunit_add_action_or_reset(test, of_overlay_fdt_apply_kunit_exit, + copy_id); +} +EXPORT_SYMBOL_GPL(of_overlay_fdt_apply_kunit); + +#endif + +KUNIT_DEFINE_ACTION_WRAPPER(of_node_put_wrapper, of_node_put, struct device_node *); + +/** + * of_node_put_kunit() - Test managed of_node_put() + * @test: test context + * @node: node to pass to `of_node_put()` + * + * Just like of_node_put(), except the node is managed by the test case and is + * automatically put with of_node_put() after the test case concludes. + */ +void of_node_put_kunit(struct kunit *test, struct device_node *node) +{ + if (kunit_add_action(test, of_node_put_wrapper, node)) { + KUNIT_FAIL(test, + "Can't allocate a kunit resource to put of_node\n"); + } +} +EXPORT_SYMBOL_GPL(of_node_put_kunit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Test managed DeviceTree APIs"); diff --git a/drivers/of/of_numa.c b/drivers/of/of_numa.c index 5949829a1b00..2ec20886d176 100644 --- a/drivers/of/of_numa.c +++ b/drivers/of/of_numa.c @@ -10,6 +10,7 @@ #include <linux/of.h> #include <linux/of_address.h> #include <linux/nodemask.h> +#include <linux/numa_memblks.h> #include <asm/numa.h> @@ -44,7 +45,7 @@ static int __init of_numa_parse_memory_nodes(void) struct device_node *np = NULL; struct resource rsrc; u32 nid; - int i, r; + int i, r = -EINVAL; for_each_node_by_type(np, "memory") { r = of_property_read_u32(np, "numa-node-id", &nid); @@ -71,7 +72,7 @@ static int __init of_numa_parse_memory_nodes(void) } } - return 0; + return r; } static int __init of_numa_parse_distance_map_v1(struct device_node *map) diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index 4d861a75d694..cbdecccca097 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -472,7 +472,6 @@ static int add_changeset_node(struct overlay_changeset *ovcs, static int build_changeset_next_level(struct overlay_changeset *ovcs, struct target *target, const struct device_node *overlay_node) { - struct device_node *child; struct property *prop; int ret; @@ -485,12 +484,11 @@ static int build_changeset_next_level(struct overlay_changeset *ovcs, } } - for_each_child_of_node(overlay_node, child) { + for_each_child_of_node_scoped(overlay_node, child) { ret = add_changeset_node(ovcs, target, child); if (ret) { pr_debug("Failed to apply node @%pOF/%pOFn, err=%d\n", target->np, child, ret); - of_node_put(child); return ret; } } @@ -1078,16 +1076,12 @@ EXPORT_SYMBOL_GPL(of_overlay_fdt_apply); */ static int find_node(struct device_node *tree, struct device_node *np) { - struct device_node *child; - if (tree == np) return 1; - for_each_child_of_node(tree, child) { - if (find_node(child, np)) { - of_node_put(child); + for_each_child_of_node_scoped(tree, child) { + if (find_node(child, np)) return 1; - } } return 0; diff --git a/drivers/of/overlay_test.c b/drivers/of/overlay_test.c new file mode 100644 index 000000000000..19a292cdeee3 --- /dev/null +++ b/drivers/of/overlay_test.c @@ -0,0 +1,115 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * KUnit tests for device tree overlays + */ +#include <linux/device/bus.h> +#include <linux/kconfig.h> +#include <linux/of.h> +#include <linux/of_platform.h> +#include <linux/platform_device.h> + +#include <kunit/of.h> +#include <kunit/test.h> + +static const char * const kunit_node_name = "kunit-test"; +static const char * const kunit_compatible = "test,empty"; + +/* Test that of_overlay_apply_kunit() adds a node to the live tree */ +static void of_overlay_apply_kunit_apply(struct kunit *test) +{ + struct device_node *np; + + KUNIT_ASSERT_EQ(test, 0, + of_overlay_apply_kunit(test, kunit_overlay_test)); + + np = of_find_node_by_name(NULL, kunit_node_name); + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, np); + of_node_put(np); +} + +/* + * Test that of_overlay_apply_kunit() creates platform devices with the + * expected device_node + */ +static void of_overlay_apply_kunit_platform_device(struct kunit *test) +{ + struct platform_device *pdev; + struct device_node *np; + + KUNIT_ASSERT_EQ(test, 0, + of_overlay_apply_kunit(test, kunit_overlay_test)); + + np = of_find_node_by_name(NULL, kunit_node_name); + of_node_put_kunit(test, np); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, np); + + pdev = of_find_device_by_node(np); + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, pdev); + if (pdev) + put_device(&pdev->dev); +} + +static int of_overlay_bus_match_compatible(struct device *dev, const void *data) +{ + return of_device_is_compatible(dev->of_node, data); +} + +/* Test that of_overlay_apply_kunit() cleans up after the test is finished */ +static void of_overlay_apply_kunit_cleanup(struct kunit *test) +{ + struct kunit fake; + struct platform_device *pdev; + struct device *dev; + struct device_node *np; + + if (!IS_ENABLED(CONFIG_OF_EARLY_FLATTREE)) + kunit_skip(test, "requires CONFIG_OF_EARLY_FLATTREE for root node"); + + kunit_init_test(&fake, "fake test", NULL); + KUNIT_ASSERT_EQ(test, fake.status, KUNIT_SUCCESS); + + KUNIT_ASSERT_EQ(test, 0, + of_overlay_apply_kunit(&fake, kunit_overlay_test)); + + np = of_find_node_by_name(NULL, kunit_node_name); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, np); + of_node_put_kunit(test, np); + + pdev = of_find_device_by_node(np); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); + put_device(&pdev->dev); /* Not derefing 'pdev' after this */ + + /* Remove overlay */ + kunit_cleanup(&fake); + + /* The node and device should be removed */ + np = of_find_node_by_name(NULL, kunit_node_name); + KUNIT_EXPECT_PTR_EQ(test, NULL, np); + of_node_put(np); + + dev = bus_find_device(&platform_bus_type, NULL, kunit_compatible, + of_overlay_bus_match_compatible); + KUNIT_EXPECT_PTR_EQ(test, NULL, dev); + put_device(dev); +} + +static struct kunit_case of_overlay_apply_kunit_test_cases[] = { + KUNIT_CASE(of_overlay_apply_kunit_apply), + KUNIT_CASE(of_overlay_apply_kunit_platform_device), + KUNIT_CASE(of_overlay_apply_kunit_cleanup), + {} +}; + +/* + * Test suite for test managed device tree overlays. + */ +static struct kunit_suite of_overlay_apply_kunit_suite = { + .name = "of_overlay_apply_kunit", + .test_cases = of_overlay_apply_kunit_test_cases, +}; + +kunit_test_suites( + &of_overlay_apply_kunit_suite, +); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("KUnit tests for device tree overlays"); diff --git a/drivers/of/platform.c b/drivers/of/platform.c index ef622d41eb5b..9bafcff3e628 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -338,7 +338,6 @@ static int of_platform_bus_create(struct device_node *bus, struct device *parent, bool strict) { const struct of_dev_auxdata *auxdata; - struct device_node *child; struct platform_device *dev; const char *bus_id = NULL; void *platform_data = NULL; @@ -382,13 +381,11 @@ static int of_platform_bus_create(struct device_node *bus, if (!dev || !of_match_node(matches, bus)) return 0; - for_each_child_of_node(bus, child) { + for_each_child_of_node_scoped(bus, child) { pr_debug(" create child: %pOF\n", child); rc = of_platform_bus_create(child, matches, lookup, &dev->dev, strict); - if (rc) { - of_node_put(child); + if (rc) break; - } } of_node_set_flag(bus, OF_POPULATED_BUS); return rc; @@ -459,7 +456,6 @@ int of_platform_populate(struct device_node *root, const struct of_dev_auxdata *lookup, struct device *parent) { - struct device_node *child; int rc = 0; root = root ? of_node_get(root) : of_find_node_by_path("/"); @@ -470,12 +466,10 @@ int of_platform_populate(struct device_node *root, pr_debug(" starting at: %pOF\n", root); device_links_supplier_sync_state_pause(); - for_each_child_of_node(root, child) { + for_each_child_of_node_scoped(root, child) { rc = of_platform_bus_create(child, matches, lookup, parent, true); - if (rc) { - of_node_put(child); + if (rc) break; - } } device_links_supplier_sync_state_resume(); @@ -732,11 +726,14 @@ static int of_platform_notify(struct notifier_block *nb, struct of_reconfig_data *rd = arg; struct platform_device *pdev_parent, *pdev; bool children_left; + struct device_node *parent; switch (of_reconfig_get_state_change(action, rd)) { case OF_RECONFIG_CHANGE_ADD: - /* verify that the parent is a bus */ - if (!of_node_check_flag(rd->dn->parent, OF_POPULATED_BUS)) + parent = rd->dn->parent; + /* verify that the parent is a bus (or the root node) */ + if (!of_node_is_root(parent) && + !of_node_check_flag(parent, OF_POPULATED_BUS)) return NOTIFY_OK; /* not for us */ /* already populated? (driver using of_populate manually) */ @@ -749,7 +746,7 @@ static int of_platform_notify(struct notifier_block *nb, */ rd->dn->fwnode.flags &= ~FWNODE_FLAG_NOT_DEVICE; /* pdev_parent may be NULL when no bus platform device */ - pdev_parent = of_find_device_by_node(rd->dn->parent); + pdev_parent = of_find_device_by_node(parent); pdev = of_platform_device_create(rd->dn, NULL, pdev_parent ? &pdev_parent->dev : NULL); platform_device_put(pdev_parent); diff --git a/drivers/of/property.c b/drivers/of/property.c index 164d77cb9445..11b922fde7af 100644 --- a/drivers/of/property.c +++ b/drivers/of/property.c @@ -452,12 +452,17 @@ EXPORT_SYMBOL_GPL(of_property_read_string); /** * of_property_match_string() - Find string in a list and return index - * @np: pointer to node containing string list property + * @np: pointer to the node containing the string list property * @propname: string list property name - * @string: pointer to string to search for in string list + * @string: pointer to the string to search for in the string list * - * This function searches a string list property and returns the index - * of a specific string value. + * Search for an exact match of string in a device node property which is a + * string of lists. + * + * Return: the index of the first occurrence of the string on success, -EINVAL + * if the property does not exist, -ENODATA if the property does not have a + * value, and -EILSEQ if the string is not null-terminated within the length of + * the property data. */ int of_property_match_string(const struct device_node *np, const char *propname, const char *string) @@ -773,16 +778,11 @@ EXPORT_SYMBOL(of_graph_get_port_parent); struct device_node *of_graph_get_remote_port_parent( const struct device_node *node) { - struct device_node *np, *pp; - /* Get remote endpoint node. */ - np = of_graph_get_remote_endpoint(node); - - pp = of_graph_get_port_parent(np); + struct device_node *np __free(device_node) = + of_graph_get_remote_endpoint(node); - of_node_put(np); - - return pp; + return of_graph_get_port_parent(np); } EXPORT_SYMBOL(of_graph_get_remote_port_parent); @@ -1064,19 +1064,15 @@ static void of_link_to_phandle(struct device_node *con_np, struct device_node *sup_np, u8 flags) { - struct device_node *tmp_np = of_node_get(sup_np); + struct device_node *tmp_np __free(device_node) = of_node_get(sup_np); /* Check that sup_np and its ancestors are available. */ while (tmp_np) { - if (of_fwnode_handle(tmp_np)->dev) { - of_node_put(tmp_np); + if (of_fwnode_handle(tmp_np)->dev) break; - } - if (!of_device_is_available(tmp_np)) { - of_node_put(tmp_np); + if (!of_device_is_available(tmp_np)) return; - } tmp_np = of_get_next_parent(tmp_np); } @@ -1440,16 +1436,13 @@ static int of_link_property(struct device_node *con_np, const char *prop_name) } while ((phandle = s->parse_prop(con_np, prop_name, i))) { - struct device_node *con_dev_np; + struct device_node *con_dev_np __free(device_node) = + s->get_con_dev ? s->get_con_dev(con_np) : of_node_get(con_np); - con_dev_np = s->get_con_dev - ? s->get_con_dev(con_np) - : of_node_get(con_np); matched = true; i++; of_link_to_phandle(con_dev_np, phandle, s->fwlink_flags); of_node_put(phandle); - of_node_put(con_dev_np); } s++; } diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c index 2780928764a4..5cf96776dd7d 100644 --- a/drivers/of/resolver.c +++ b/drivers/of/resolver.c @@ -150,7 +150,7 @@ static int node_name_cmp(const struct device_node *dn1, static int adjust_local_phandle_references(struct device_node *local_fixups, struct device_node *overlay, int phandle_delta) { - struct device_node *child, *overlay_child; + struct device_node *overlay_child; struct property *prop_fix, *prop; int err, i, count; unsigned int off; @@ -194,7 +194,7 @@ static int adjust_local_phandle_references(struct device_node *local_fixups, * The roots of the subtrees are the overlay's __local_fixups__ node * and the overlay's root node. */ - for_each_child_of_node(local_fixups, child) { + for_each_child_of_node_scoped(local_fixups, child) { for_each_child_of_node(overlay, overlay_child) if (!node_name_cmp(child, overlay_child)) { @@ -202,17 +202,13 @@ static int adjust_local_phandle_references(struct device_node *local_fixups, break; } - if (!overlay_child) { - of_node_put(child); + if (!overlay_child) return -EINVAL; - } err = adjust_local_phandle_references(child, overlay_child, phandle_delta); - if (err) { - of_node_put(child); + if (err) return err; - } } return 0; diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index c830f346df45..daf9a2dddd7e 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -900,8 +900,8 @@ static void __init of_unittest_changeset(void) unittest(!of_find_node_by_path("/testcase-data/changeset/n2/n21"), "'%pOF' still present after revert\n", n21); - ppremove = of_find_property(parent, "prop-remove", NULL); - unittest(ppremove, "failed to find removed prop after revert\n"); + unittest(of_property_present(parent, "prop-remove"), + "failed to find removed prop after revert\n"); ret = of_property_read_string(parent, "prop-update", &propstr); unittest(!ret, "failed to find updated prop after revert\n"); @@ -1861,7 +1861,7 @@ static int __init unittest_data_add(void) struct device_node *unittest_data_node = NULL, *np; /* * __dtbo_testcases_begin[] and __dtbo_testcases_end[] are magically - * created by cmd_dt_S_dtbo in scripts/Makefile.lib + * created by cmd_wrap_S_dtbo in scripts/Makefile.dtbs */ extern uint8_t __dtbo_testcases_begin[]; extern uint8_t __dtbo_testcases_end[]; @@ -3525,7 +3525,7 @@ out_skip_tests: /* * __dtbo_##overlay_name##_begin[] and __dtbo_##overlay_name##_end[] are - * created by cmd_dt_S_dtbo in scripts/Makefile.lib + * created by cmd_wrap_S_dtbo in scripts/Makefile.dtbs */ #define OVERLAY_INFO_EXTERN(overlay_name) \ |