From d6ce4f0ea19c32f10867ed93d8386924326ab474 Mon Sep 17 00:00:00 2001 From: Ruan Jinjie Date: Thu, 27 Jul 2023 16:02:46 +0800 Subject: of: unittest: fix null pointer dereferencing in of_unittest_find_node_by_name() when kmalloc() fail to allocate memory in kasprintf(), name or full_name will be NULL, strcmp() will cause null pointer dereference. Fixes: 0d638a07d3a1 ("of: Convert to using %pOF instead of full_name") Signed-off-by: Ruan Jinjie Link: https://lore.kernel.org/r/20230727080246.519539-1-ruanjinjie@huawei.com Signed-off-by: Rob Herring --- drivers/of/unittest.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index a406a12eb208..e5b0eea8011c 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -77,7 +77,7 @@ static void __init of_unittest_find_node_by_name(void) np = of_find_node_by_path("/testcase-data"); name = kasprintf(GFP_KERNEL, "%pOF", np); - unittest(np && !strcmp("/testcase-data", name), + unittest(np && name && !strcmp("/testcase-data", name), "find /testcase-data failed\n"); of_node_put(np); kfree(name); @@ -88,14 +88,14 @@ static void __init of_unittest_find_node_by_name(void) np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a"); name = kasprintf(GFP_KERNEL, "%pOF", np); - unittest(np && !strcmp("/testcase-data/phandle-tests/consumer-a", name), + unittest(np && name && !strcmp("/testcase-data/phandle-tests/consumer-a", name), "find /testcase-data/phandle-tests/consumer-a failed\n"); of_node_put(np); kfree(name); np = of_find_node_by_path("testcase-alias"); name = kasprintf(GFP_KERNEL, "%pOF", np); - unittest(np && !strcmp("/testcase-data", name), + unittest(np && name && !strcmp("/testcase-data", name), "find testcase-alias failed\n"); of_node_put(np); kfree(name); @@ -106,7 +106,7 @@ static void __init of_unittest_find_node_by_name(void) np = of_find_node_by_path("testcase-alias/phandle-tests/consumer-a"); name = kasprintf(GFP_KERNEL, "%pOF", np); - unittest(np && !strcmp("/testcase-data/phandle-tests/consumer-a", name), + unittest(np && name && !strcmp("/testcase-data/phandle-tests/consumer-a", name), "find testcase-alias/phandle-tests/consumer-a failed\n"); of_node_put(np); kfree(name); @@ -1533,6 +1533,8 @@ static void attach_node_and_children(struct device_node *np) const char *full_name; full_name = kasprintf(GFP_KERNEL, "%pOF", np); + if (!full_name) + return; if (!strcmp(full_name, "/__local_fixups__") || !strcmp(full_name, "/__fixups__")) { -- cgit v1.2.3-58-ga151 From 73aca58b781e3e3d52bb7247b374fb5334a05001 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 17 Jul 2023 08:37:16 -0600 Subject: of: Move of_platform_register_reconfig_notifier() into DT core There's no reason the generic platform bus code needs to call of_platform_register_reconfig_notifier(). The notifier can be setup before the platform bus is. Let's move it into of_core_init() which is called just before platform_bus_init() instead to keep more of the DT bits in the DT code. Reviewed-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20230717143718.1715773-1-robh@kernel.org Signed-off-by: Rob Herring --- drivers/base/platform.c | 2 +- drivers/of/base.c | 1 + drivers/of/of_private.h | 6 ++++++ drivers/of/platform.c | 2 ++ include/linux/of_platform.h | 6 ------ 5 files changed, 10 insertions(+), 7 deletions(-) (limited to 'drivers/of') diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 77510e4f47de..76bfcba25003 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -1528,6 +1528,6 @@ int __init platform_bus_init(void) error = bus_register(&platform_bus_type); if (error) device_unregister(&platform_bus); - of_platform_register_reconfig_notifier(); + return error; } diff --git a/drivers/of/base.c b/drivers/of/base.c index 166fb7d75337..e235f3a57ea8 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -167,6 +167,7 @@ void __init of_core_init(void) { struct device_node *np; + of_platform_register_reconfig_notifier(); /* Create the kset, and register existing nodes */ mutex_lock(&of_mutex); diff --git a/drivers/of/of_private.h b/drivers/of/of_private.h index b57f1014e419..f38397c7b582 100644 --- a/drivers/of/of_private.h +++ b/drivers/of/of_private.h @@ -60,6 +60,12 @@ static inline int of_property_notify(int action, struct device_node *np, } #endif /* CONFIG_OF_DYNAMIC */ +#if defined(CONFIG_OF_DYNAMIC) && defined(CONFIG_OF_ADDRESS) +void of_platform_register_reconfig_notifier(void); +#else +static inline void of_platform_register_reconfig_notifier(void) { } +#endif + #if defined(CONFIG_OF_KOBJ) int of_node_is_attached(const struct device_node *node); int __of_add_property_sysfs(struct device_node *np, struct property *pp); diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 051e29b7ad2b..e71adb394b41 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -21,6 +21,8 @@ #include #include +#include "of_private.h" + const struct of_device_id of_default_bus_match_table[] = { { .compatible = "simple-bus", }, { .compatible = "simple-mfd", }, diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h index d8045bcfc35e..fadfea575485 100644 --- a/include/linux/of_platform.h +++ b/include/linux/of_platform.h @@ -127,10 +127,4 @@ static inline int devm_of_platform_populate(struct device *dev) static inline void devm_of_platform_depopulate(struct device *dev) { } #endif -#if defined(CONFIG_OF_DYNAMIC) && defined(CONFIG_OF_ADDRESS) -extern void of_platform_register_reconfig_notifier(void); -#else -static inline void of_platform_register_reconfig_notifier(void) { } -#endif - #endif /* _LINUX_OF_PLATFORM_H */ -- cgit v1.2.3-58-ga151 From 66a4210bc82e024e6de0f94298ad9230984a5924 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Mon, 17 Jul 2023 08:37:17 -0600 Subject: of: Move of_device_{add,register,unregister} to platform.c The declarations for of_device_{add,register,unregister} were moved into of_platform.h, so the implementations should be moved to platform.c as well. Reviewed-by: Greg Kroah-Hartman Link: https://lore.kernel.org/r/20230717143718.1715773-2-robh@kernel.org Signed-off-by: Rob Herring --- drivers/of/device.c | 32 -------------------------------- drivers/of/platform.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 32 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/device.c b/drivers/of/device.c index 0f00f1b80708..2319e0e73048 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -32,25 +32,6 @@ const struct of_device_id *of_match_device(const struct of_device_id *matches, } EXPORT_SYMBOL(of_match_device); -int of_device_add(struct platform_device *ofdev) -{ - BUG_ON(ofdev->dev.of_node == NULL); - - /* name and id have to be set so that the platform bus doesn't get - * confused on matching */ - ofdev->name = dev_name(&ofdev->dev); - ofdev->id = PLATFORM_DEVID_NONE; - - /* - * If this device has not binding numa node in devicetree, that is - * of_node_to_nid returns NUMA_NO_NODE. device_add will assume that this - * device is on the same node as the parent. - */ - set_dev_node(&ofdev->dev, of_node_to_nid(ofdev->dev.of_node)); - - return device_add(&ofdev->dev); -} - static void of_dma_set_restricted_buffer(struct device *dev, struct device_node *np) { @@ -221,19 +202,6 @@ int of_dma_configure_id(struct device *dev, struct device_node *np, } EXPORT_SYMBOL_GPL(of_dma_configure_id); -int of_device_register(struct platform_device *pdev) -{ - device_initialize(&pdev->dev); - return of_device_add(pdev); -} -EXPORT_SYMBOL(of_device_register); - -void of_device_unregister(struct platform_device *ofdev) -{ - device_unregister(&ofdev->dev); -} -EXPORT_SYMBOL(of_device_unregister); - const void *of_device_get_match_data(const struct device *dev) { const struct of_device_id *match; diff --git a/drivers/of/platform.c b/drivers/of/platform.c index e71adb394b41..8d03d9e65ef9 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -56,6 +56,38 @@ struct platform_device *of_find_device_by_node(struct device_node *np) } EXPORT_SYMBOL(of_find_device_by_node); +int of_device_add(struct platform_device *ofdev) +{ + BUG_ON(ofdev->dev.of_node == NULL); + + /* name and id have to be set so that the platform bus doesn't get + * confused on matching */ + ofdev->name = dev_name(&ofdev->dev); + ofdev->id = PLATFORM_DEVID_NONE; + + /* + * If this device has not binding numa node in devicetree, that is + * of_node_to_nid returns NUMA_NO_NODE. device_add will assume that this + * device is on the same node as the parent. + */ + set_dev_node(&ofdev->dev, of_node_to_nid(ofdev->dev.of_node)); + + return device_add(&ofdev->dev); +} + +int of_device_register(struct platform_device *pdev) +{ + device_initialize(&pdev->dev); + return of_device_add(pdev); +} +EXPORT_SYMBOL(of_device_register); + +void of_device_unregister(struct platform_device *ofdev) +{ + device_unregister(&ofdev->dev); +} +EXPORT_SYMBOL(of_device_unregister); + #ifdef CONFIG_OF_ADDRESS /* * The following routines scan a subtree and registers a device for -- cgit v1.2.3-58-ga151 From 2b9583244aad15020af376bce7113a8978e0bd5c Mon Sep 17 00:00:00 2001 From: Ruan Jinjie Date: Tue, 8 Aug 2023 17:40:43 +0800 Subject: of: unittest: Remove redundant of_match_ptr() The driver depends on CONFIG_OF, it is not necessary to use of_match_ptr() here. Signed-off-by: Ruan Jinjie Link: https://lore.kernel.org/r/20230808094043.2732158-1-ruanjinjie@huawei.com Signed-off-by: Rob Herring --- drivers/of/unittest.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index e5b0eea8011c..3444386ceb02 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -1696,7 +1696,7 @@ static struct platform_driver unittest_driver = { .remove_new = unittest_remove, .driver = { .name = "unittest", - .of_match_table = of_match_ptr(unittest_match), + .of_match_table = unittest_match, }, }; @@ -1797,7 +1797,7 @@ static struct platform_driver unittest_gpio_driver = { .remove_new = unittest_gpio_remove, .driver = { .name = "unittest-gpio", - .of_match_table = of_match_ptr(unittest_gpio_id), + .of_match_table = unittest_gpio_id, }, }; @@ -2624,7 +2624,7 @@ static struct platform_driver unittest_i2c_bus_driver = { .remove_new = unittest_i2c_bus_remove, .driver = { .name = "unittest-i2c-bus", - .of_match_table = of_match_ptr(unittest_i2c_bus_match), + .of_match_table = unittest_i2c_bus_match, }, }; -- cgit v1.2.3-58-ga151 From 27a02f265e25a6d6136d07d0187fd02fe1691fd7 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 18 Aug 2023 15:40:58 -0500 Subject: of: dynamic: Refactor changeset action printing to common helpers Several places print the changeset action with node and property details. Refactor these into a common printing helper. The complicating factor is some prints are debug and some are errors. Solve this with a bit of preprocessor magic. Some cases printed the 'cset' which was the changeset entry pointer rather than the whole changeset itself. The changeset entry is not all that interesting and gets obfuscated by default anyways. So just drop it. Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20230801-dt-changeset-fixes-v3-3-5f0410e007dd@kernel.org Signed-off-by: Rob Herring --- drivers/of/dynamic.c | 53 +++++++++++----------------------------------------- 1 file changed, 11 insertions(+), 42 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c index 4999636eaa92..b2b921bcbbcb 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c @@ -72,27 +72,21 @@ static const char *action_names[] = { [OF_RECONFIG_UPDATE_PROPERTY] = "UPDATE_PROPERTY", }; +#define _do_print(func, prefix, action, node, prop, ...) ({ \ + func("changeset: " prefix "%-15s %pOF%s%s\n", \ + ##__VA_ARGS__, action_names[action], node, \ + prop ? ":" : "", prop ? prop->name : ""); \ +}) +#define of_changeset_action_err(...) _do_print(pr_err, __VA_ARGS__) +#define of_changeset_action_debug(...) _do_print(pr_debug, __VA_ARGS__) + int of_reconfig_notify(unsigned long action, struct of_reconfig_data *p) { int rc; -#ifdef DEBUG struct of_reconfig_data *pr = p; - switch (action) { - case OF_RECONFIG_ATTACH_NODE: - case OF_RECONFIG_DETACH_NODE: - pr_debug("notify %-15s %pOF\n", action_names[action], - pr->dn); - break; - case OF_RECONFIG_ADD_PROPERTY: - case OF_RECONFIG_REMOVE_PROPERTY: - case OF_RECONFIG_UPDATE_PROPERTY: - pr_debug("notify %-15s %pOF:%s\n", action_names[action], - pr->dn, pr->prop->name); - break; + of_changeset_action_debug("notify: ", action, pr->dn, pr->prop); - } -#endif rc = blocking_notifier_call_chain(&of_reconfig_chain, action, p); return notifier_to_errno(rc); } @@ -503,30 +497,6 @@ static void __of_changeset_entry_destroy(struct of_changeset_entry *ce) kfree(ce); } -#ifdef DEBUG -static void __of_changeset_entry_dump(struct of_changeset_entry *ce) -{ - switch (ce->action) { - case OF_RECONFIG_ADD_PROPERTY: - case OF_RECONFIG_REMOVE_PROPERTY: - case OF_RECONFIG_UPDATE_PROPERTY: - pr_debug("cset<%p> %-15s %pOF/%s\n", ce, action_names[ce->action], - ce->np, ce->prop->name); - break; - case OF_RECONFIG_ATTACH_NODE: - case OF_RECONFIG_DETACH_NODE: - pr_debug("cset<%p> %-15s %pOF\n", ce, action_names[ce->action], - ce->np); - break; - } -} -#else -static inline void __of_changeset_entry_dump(struct of_changeset_entry *ce) -{ - /* empty */ -} -#endif - static void __of_changeset_entry_invert(struct of_changeset_entry *ce, struct of_changeset_entry *rce) { @@ -598,7 +568,7 @@ static int __of_changeset_entry_apply(struct of_changeset_entry *ce) unsigned long flags; int ret = 0; - __of_changeset_entry_dump(ce); + of_changeset_action_debug("apply: ", ce->action, ce->np, ce->prop); raw_spin_lock_irqsave(&devtree_lock, flags); switch (ce->action) { @@ -642,8 +612,7 @@ static int __of_changeset_entry_apply(struct of_changeset_entry *ce) raw_spin_unlock_irqrestore(&devtree_lock, flags); if (ret) { - pr_err("changeset: apply failed: %-15s %pOF:%s\n", - action_names[ce->action], ce->np, ce->prop->name); + of_changeset_action_err("apply failed: ", ce->action, ce->np, ce->prop); return ret; } -- cgit v1.2.3-58-ga151 From 420f0de965a80b7060d23d2c23cddaed4e4ad2eb Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 18 Aug 2023 15:40:59 -0500 Subject: of: dynamic: Fix race in getting old property when updating property __of_update_property() returns the existing property if there is one, but that value is never added to the changeset. Updates work because the existing property was also retrieved before in of_changeset_action(), but that is racy as of_changeset_action() doesn't hold any locks. The property could be changed before the changeset is applied. Reviewed-by: Geert Uytterhoeven Tested-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20230801-dt-changeset-fixes-v3-4-5f0410e007dd@kernel.org Signed-off-by: Rob Herring --- drivers/of/dynamic.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c index b2b921bcbbcb..38dc536bc64c 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c @@ -564,7 +564,7 @@ static int __of_changeset_entry_notify(struct of_changeset_entry *ce, static int __of_changeset_entry_apply(struct of_changeset_entry *ce) { - struct property *old_prop, **propp; + struct property **propp; unsigned long flags; int ret = 0; @@ -604,7 +604,7 @@ static int __of_changeset_entry_apply(struct of_changeset_entry *ce) } } - ret = __of_update_property(ce->np, ce->prop, &old_prop); + ret = __of_update_property(ce->np, ce->prop, &ce->old_prop); break; default: ret = -EINVAL; @@ -908,9 +908,6 @@ int of_changeset_action(struct of_changeset *ocs, unsigned long action, ce->np = of_node_get(np); ce->prop = prop; - if (action == OF_RECONFIG_UPDATE_PROPERTY && prop) - ce->old_prop = of_find_property(np, prop->name, NULL); - /* add it to the list */ list_add_tail(&ce->node, &ocs->entries); return 0; -- cgit v1.2.3-58-ga151 From 6701c2c76a1ed4bb442235204820cfa24e8d5b9c Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 18 Aug 2023 15:41:00 -0500 Subject: of: dynamic: Move dead property list check into property add/update functions The changeset code checks for a property in the deadprops list when adding/updating a property, but of_add_property() and of_update_property() do not. As the users of these functions are pretty simple, they have not hit this scenario or else the property lists would get corrupted. With this there are 3 cases of removing a property from either deadprops or properties lists, so add a helper to find and remove a matching property. Reviewed-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/20230801-dt-changeset-fixes-v3-5-5f0410e007dd@kernel.org Signed-off-by: Rob Herring --- drivers/of/base.c | 37 ++++++++++++++++++++++++------------- drivers/of/dynamic.c | 19 ------------------- 2 files changed, 24 insertions(+), 32 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/base.c b/drivers/of/base.c index e235f3a57ea8..3f9ddd18ff4b 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1530,6 +1530,20 @@ int of_count_phandle_with_args(const struct device_node *np, const char *list_na } EXPORT_SYMBOL(of_count_phandle_with_args); +static struct property *__of_remove_property_from_list(struct property **list, struct property *prop) +{ + struct property **next; + + for (next = list; *next; next = &(*next)->next) { + if (*next == prop) { + *next = prop->next; + prop->next = NULL; + return prop; + } + } + return NULL; +} + /** * __of_add_property - Add a property to a node without lock operations * @np: Caller's Device Node @@ -1539,6 +1553,8 @@ int __of_add_property(struct device_node *np, struct property *prop) { struct property **next; + __of_remove_property_from_list(&np->deadprops, prop); + prop->next = NULL; next = &np->properties; while (*next) { @@ -1583,21 +1599,14 @@ EXPORT_SYMBOL_GPL(of_add_property); int __of_remove_property(struct device_node *np, struct property *prop) { - struct property **next; - - for (next = &np->properties; *next; next = &(*next)->next) { - if (*next == prop) - break; + if (__of_remove_property_from_list(&np->properties, prop)) { + /* Found the property, add it to deadprops list */ + prop->next = np->deadprops; + np->deadprops = prop; + return 0; } - if (*next == NULL) - return -ENODEV; - - /* found the node */ - *next = prop->next; - prop->next = np->deadprops; - np->deadprops = prop; - return 0; + return -ENODEV; } /** @@ -1641,6 +1650,8 @@ int __of_update_property(struct device_node *np, struct property *newprop, { struct property **next, *oldprop; + __of_remove_property_from_list(&np->deadprops, newprop); + for (next = &np->properties; *next; next = &(*next)->next) { if (of_prop_cmp((*next)->name, newprop->name) == 0) break; diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c index 38dc536bc64c..713910782a9d 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c @@ -564,7 +564,6 @@ static int __of_changeset_entry_notify(struct of_changeset_entry *ce, static int __of_changeset_entry_apply(struct of_changeset_entry *ce) { - struct property **propp; unsigned long flags; int ret = 0; @@ -579,15 +578,6 @@ static int __of_changeset_entry_apply(struct of_changeset_entry *ce) __of_detach_node(ce->np); break; case OF_RECONFIG_ADD_PROPERTY: - /* If the property is in deadprops then it must be removed */ - for (propp = &ce->np->deadprops; *propp; propp = &(*propp)->next) { - if (*propp == ce->prop) { - *propp = ce->prop->next; - ce->prop->next = NULL; - break; - } - } - ret = __of_add_property(ce->np, ce->prop); break; case OF_RECONFIG_REMOVE_PROPERTY: @@ -595,15 +585,6 @@ static int __of_changeset_entry_apply(struct of_changeset_entry *ce) break; case OF_RECONFIG_UPDATE_PROPERTY: - /* If the property is in deadprops then it must be removed */ - for (propp = &ce->np->deadprops; *propp; propp = &(*propp)->next) { - if (*propp == ce->prop) { - *propp = ce->prop->next; - ce->prop->next = NULL; - break; - } - } - ret = __of_update_property(ce->np, ce->prop, &ce->old_prop); break; default: -- cgit v1.2.3-58-ga151 From fab610be30dbaa4ef5dcfabe4dc498c557a1b7ad Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Fri, 18 Aug 2023 15:41:01 -0500 Subject: of: Refactor node and property manipulation function locking All callers of __of_{add,remove,update}_property() and __of_{attach,detach}_node() wrap the call with the devtree_lock spinlock. Let's move the spinlock into the functions. This allows moving the sysfs update functions into those functions as well. Link: https://lore.kernel.org/r/20230801-dt-changeset-fixes-v3-6-5f0410e007dd@kernel.org Signed-off-by: Rob Herring --- drivers/of/base.c | 62 ++++++++++++++++++++++++++++------------------------ drivers/of/dynamic.c | 51 ++++++++++++++---------------------------- 2 files changed, 49 insertions(+), 64 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/base.c b/drivers/of/base.c index 3f9ddd18ff4b..8d93cb6ea9cd 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -1551,21 +1551,32 @@ static struct property *__of_remove_property_from_list(struct property **list, s */ int __of_add_property(struct device_node *np, struct property *prop) { + int rc = 0; + unsigned long flags; struct property **next; + raw_spin_lock_irqsave(&devtree_lock, flags); + __of_remove_property_from_list(&np->deadprops, prop); prop->next = NULL; next = &np->properties; while (*next) { - if (strcmp(prop->name, (*next)->name) == 0) + if (strcmp(prop->name, (*next)->name) == 0) { /* duplicate ! don't insert it */ - return -EEXIST; - + rc = -EEXIST; + goto out_unlock; + } next = &(*next)->next; } *next = prop; +out_unlock: + raw_spin_unlock_irqrestore(&devtree_lock, flags); + if (rc) + return rc; + + __of_add_property_sysfs(np, prop); return 0; } @@ -1576,18 +1587,10 @@ int __of_add_property(struct device_node *np, struct property *prop) */ int of_add_property(struct device_node *np, struct property *prop) { - unsigned long flags; int rc; mutex_lock(&of_mutex); - - raw_spin_lock_irqsave(&devtree_lock, flags); rc = __of_add_property(np, prop); - raw_spin_unlock_irqrestore(&devtree_lock, flags); - - if (!rc) - __of_add_property_sysfs(np, prop); - mutex_unlock(&of_mutex); if (!rc) @@ -1599,14 +1602,24 @@ EXPORT_SYMBOL_GPL(of_add_property); int __of_remove_property(struct device_node *np, struct property *prop) { + unsigned long flags; + int rc = -ENODEV; + + raw_spin_lock_irqsave(&devtree_lock, flags); + if (__of_remove_property_from_list(&np->properties, prop)) { /* Found the property, add it to deadprops list */ prop->next = np->deadprops; np->deadprops = prop; - return 0; + rc = 0; } - return -ENODEV; + raw_spin_unlock_irqrestore(&devtree_lock, flags); + if (rc) + return rc; + + __of_remove_property_sysfs(np, prop); + return 0; } /** @@ -1621,21 +1634,13 @@ int __of_remove_property(struct device_node *np, struct property *prop) */ int of_remove_property(struct device_node *np, struct property *prop) { - unsigned long flags; int rc; if (!prop) return -ENODEV; mutex_lock(&of_mutex); - - raw_spin_lock_irqsave(&devtree_lock, flags); rc = __of_remove_property(np, prop); - raw_spin_unlock_irqrestore(&devtree_lock, flags); - - if (!rc) - __of_remove_property_sysfs(np, prop); - mutex_unlock(&of_mutex); if (!rc) @@ -1649,6 +1654,9 @@ int __of_update_property(struct device_node *np, struct property *newprop, struct property **oldpropp) { struct property **next, *oldprop; + unsigned long flags; + + raw_spin_lock_irqsave(&devtree_lock, flags); __of_remove_property_from_list(&np->deadprops, newprop); @@ -1670,6 +1678,10 @@ int __of_update_property(struct device_node *np, struct property *newprop, *next = newprop; } + raw_spin_unlock_irqrestore(&devtree_lock, flags); + + __of_update_property_sysfs(np, newprop, oldprop); + return 0; } @@ -1685,21 +1697,13 @@ int __of_update_property(struct device_node *np, struct property *newprop, int of_update_property(struct device_node *np, struct property *newprop) { struct property *oldprop; - unsigned long flags; int rc; if (!newprop->name) return -EINVAL; mutex_lock(&of_mutex); - - raw_spin_lock_irqsave(&devtree_lock, flags); rc = __of_update_property(np, newprop, &oldprop); - raw_spin_unlock_irqrestore(&devtree_lock, flags); - - if (!rc) - __of_update_property_sysfs(np, newprop, oldprop); - mutex_unlock(&of_mutex); if (!rc) diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c index 713910782a9d..3a9e38dcf9c2 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c @@ -198,6 +198,9 @@ static void __of_attach_node(struct device_node *np) { const __be32 *phandle; int sz; + unsigned long flags; + + raw_spin_lock_irqsave(&devtree_lock, flags); if (!of_node_check_flag(np, OF_OVERLAY)) { np->name = __of_get_property(np, "name", NULL); @@ -220,6 +223,10 @@ static void __of_attach_node(struct device_node *np) np->parent->child = np; of_node_clear_flag(np, OF_DETACHED); np->fwnode.flags |= FWNODE_FLAG_NOT_DEVICE; + + raw_spin_unlock_irqrestore(&devtree_lock, flags); + + __of_attach_node_sysfs(np); } /** @@ -229,17 +236,12 @@ static void __of_attach_node(struct device_node *np) int of_attach_node(struct device_node *np) { struct of_reconfig_data rd; - unsigned long flags; memset(&rd, 0, sizeof(rd)); rd.dn = np; mutex_lock(&of_mutex); - raw_spin_lock_irqsave(&devtree_lock, flags); __of_attach_node(np); - raw_spin_unlock_irqrestore(&devtree_lock, flags); - - __of_attach_node_sysfs(np); mutex_unlock(&of_mutex); of_reconfig_notify(OF_RECONFIG_ATTACH_NODE, &rd); @@ -250,13 +252,15 @@ int of_attach_node(struct device_node *np) void __of_detach_node(struct device_node *np) { struct device_node *parent; + unsigned long flags; - if (WARN_ON(of_node_check_flag(np, OF_DETACHED))) - return; + raw_spin_lock_irqsave(&devtree_lock, flags); parent = np->parent; - if (WARN_ON(!parent)) + if (WARN_ON(of_node_check_flag(np, OF_DETACHED) || !parent)) { + raw_spin_unlock_irqrestore(&devtree_lock, flags); return; + } if (parent->child == np) parent->child = np->sibling; @@ -273,6 +277,10 @@ void __of_detach_node(struct device_node *np) /* race with of_find_node_by_phandle() prevented by devtree_lock */ __of_phandle_cache_inv_entry(np->phandle); + + raw_spin_unlock_irqrestore(&devtree_lock, flags); + + __of_detach_node_sysfs(np); } /** @@ -282,17 +290,12 @@ void __of_detach_node(struct device_node *np) int of_detach_node(struct device_node *np) { struct of_reconfig_data rd; - unsigned long flags; memset(&rd, 0, sizeof(rd)); rd.dn = np; mutex_lock(&of_mutex); - raw_spin_lock_irqsave(&devtree_lock, flags); __of_detach_node(np); - raw_spin_unlock_irqrestore(&devtree_lock, flags); - - __of_detach_node_sysfs(np); mutex_unlock(&of_mutex); of_reconfig_notify(OF_RECONFIG_DETACH_NODE, &rd); @@ -564,12 +567,10 @@ static int __of_changeset_entry_notify(struct of_changeset_entry *ce, static int __of_changeset_entry_apply(struct of_changeset_entry *ce) { - unsigned long flags; int ret = 0; of_changeset_action_debug("apply: ", ce->action, ce->np, ce->prop); - raw_spin_lock_irqsave(&devtree_lock, flags); switch (ce->action) { case OF_RECONFIG_ATTACH_NODE: __of_attach_node(ce->np); @@ -590,32 +591,12 @@ static int __of_changeset_entry_apply(struct of_changeset_entry *ce) default: ret = -EINVAL; } - raw_spin_unlock_irqrestore(&devtree_lock, flags); if (ret) { of_changeset_action_err("apply failed: ", ce->action, ce->np, ce->prop); return ret; } - switch (ce->action) { - case OF_RECONFIG_ATTACH_NODE: - __of_attach_node_sysfs(ce->np); - break; - case OF_RECONFIG_DETACH_NODE: - __of_detach_node_sysfs(ce->np); - break; - case OF_RECONFIG_ADD_PROPERTY: - /* ignore duplicate names */ - __of_add_property_sysfs(ce->np, ce->prop); - break; - case OF_RECONFIG_REMOVE_PROPERTY: - __of_remove_property_sysfs(ce->np, ce->prop); - break; - case OF_RECONFIG_UPDATE_PROPERTY: - __of_update_property_sysfs(ce->np, ce->prop, ce->old_prop); - break; - } - return 0; } -- cgit v1.2.3-58-ga151 From ef04d2801c5d239b83932f8ce97af1d4a1ec1cf7 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 22 Aug 2023 13:27:22 +0530 Subject: of: Move of_skipped_node_table within #ifdef CONFIG_OF_ADDRESS The `struct of_skipped_node_table` is used only when CONFIG_OF_ADDRESS is defined, move it within the #ifdef/#endif to avoid warnings on configurations where CONFIG_OF_ADDRESS isn't defined. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202308212037.YopffWSU-lkp@intel.com/ Signed-off-by: Viresh Kumar Link: https://lore.kernel.org/r/73dea4f4b389359a8beadbc77b00eb26853f9ab5.1692691032.git.viresh.kumar@linaro.org Signed-off-by: Rob Herring --- drivers/of/platform.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/platform.c b/drivers/of/platform.c index d328bbb679c7..f235ab55b91e 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -33,11 +33,6 @@ const struct of_device_id of_default_bus_match_table[] = { {} /* Empty terminated list */ }; -static const struct of_device_id of_skipped_node_table[] = { - { .compatible = "operating-points-v2", }, - {} /* Empty terminated list */ -}; - /** * of_find_device_by_node - Find the platform_device associated with a node * @np: Pointer to device tree node @@ -89,6 +84,11 @@ void of_device_unregister(struct platform_device *ofdev) EXPORT_SYMBOL(of_device_unregister); #ifdef CONFIG_OF_ADDRESS +static const struct of_device_id of_skipped_node_table[] = { + { .compatible = "operating-points-v2", }, + {} /* Empty terminated list */ +}; + /* * The following routines scan a subtree and registers a device for * each applicable node. -- cgit v1.2.3-58-ga151 From b544fc2b8606d718d0cc788ff2ea2492871df488 Mon Sep 17 00:00:00 2001 From: Lizhi Hou Date: Tue, 15 Aug 2023 10:19:56 -0700 Subject: of: dynamic: Add interfaces for creating device node dynamically MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit of_changeset_create_node() creates device node dynamically and attaches the newly created node to a changeset. Expand of_changeset APIs to handle specific types of properties. of_changeset_add_prop_string() of_changeset_add_prop_string_array() of_changeset_add_prop_u32_array() Signed-off-by: Clément Léger Signed-off-by: Lizhi Hou Link: https://lore.kernel.org/r/1692120000-46900-2-git-send-email-lizhi.hou@amd.com Signed-off-by: Rob Herring --- drivers/of/dynamic.c | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++ drivers/of/unittest.c | 19 +++++- include/linux/of.h | 23 +++++++ 3 files changed, 205 insertions(+), 1 deletion(-) (limited to 'drivers/of') diff --git a/drivers/of/dynamic.c b/drivers/of/dynamic.c index 3a9e38dcf9c2..0a3483e247a8 100644 --- a/drivers/of/dynamic.c +++ b/drivers/of/dynamic.c @@ -483,6 +483,38 @@ struct device_node *__of_node_dup(const struct device_node *np, return NULL; } +/** + * of_changeset_create_node - Dynamically create a device node and attach to + * a given changeset. + * + * @ocs: Pointer to changeset + * @parent: Pointer to parent device node + * @full_name: Node full name + * + * Return: Pointer to the created device node or NULL in case of an error. + */ +struct device_node *of_changeset_create_node(struct of_changeset *ocs, + struct device_node *parent, + const char *full_name) +{ + struct device_node *np; + int ret; + + np = __of_node_dup(NULL, full_name); + if (!np) + return NULL; + np->parent = parent; + + ret = of_changeset_attach_node(ocs, np); + if (ret) { + of_node_put(np); + return NULL; + } + + return np; +} +EXPORT_SYMBOL(of_changeset_create_node); + static void __of_changeset_entry_destroy(struct of_changeset_entry *ce) { if (ce->action == OF_RECONFIG_ATTACH_NODE && @@ -875,3 +907,135 @@ int of_changeset_action(struct of_changeset *ocs, unsigned long action, return 0; } EXPORT_SYMBOL_GPL(of_changeset_action); + +static int of_changeset_add_prop_helper(struct of_changeset *ocs, + struct device_node *np, + const struct property *pp) +{ + struct property *new_pp; + int ret; + + new_pp = __of_prop_dup(pp, GFP_KERNEL); + if (!new_pp) + return -ENOMEM; + + ret = of_changeset_add_property(ocs, np, new_pp); + if (ret) { + kfree(new_pp->name); + kfree(new_pp->value); + kfree(new_pp); + } + + return ret; +} + +/** + * of_changeset_add_prop_string - Add a string property to a changeset + * + * @ocs: changeset pointer + * @np: device node pointer + * @prop_name: name of the property to be added + * @str: pointer to null terminated string + * + * Create a string property and add it to a changeset. + * + * Return: 0 on success, a negative error value in case of an error. + */ +int of_changeset_add_prop_string(struct of_changeset *ocs, + struct device_node *np, + const char *prop_name, const char *str) +{ + struct property prop; + + prop.name = (char *)prop_name; + prop.length = strlen(str) + 1; + prop.value = (void *)str; + + return of_changeset_add_prop_helper(ocs, np, &prop); +} +EXPORT_SYMBOL_GPL(of_changeset_add_prop_string); + +/** + * of_changeset_add_prop_string_array - Add a string list property to + * a changeset + * + * @ocs: changeset pointer + * @np: device node pointer + * @prop_name: name of the property to be added + * @str_array: pointer to an array of null terminated strings + * @sz: number of string array elements + * + * Create a string list property and add it to a changeset. + * + * Return: 0 on success, a negative error value in case of an error. + */ +int of_changeset_add_prop_string_array(struct of_changeset *ocs, + struct device_node *np, + const char *prop_name, + const char **str_array, size_t sz) +{ + struct property prop; + int i, ret; + char *vp; + + prop.name = (char *)prop_name; + + prop.length = 0; + for (i = 0; i < sz; i++) + prop.length += strlen(str_array[i]) + 1; + + prop.value = kmalloc(prop.length, GFP_KERNEL); + if (!prop.value) + return -ENOMEM; + + vp = prop.value; + for (i = 0; i < sz; i++) { + vp += snprintf(vp, (char *)prop.value + prop.length - vp, "%s", + str_array[i]) + 1; + } + ret = of_changeset_add_prop_helper(ocs, np, &prop); + kfree(prop.value); + + return ret; +} +EXPORT_SYMBOL_GPL(of_changeset_add_prop_string_array); + +/** + * of_changeset_add_prop_u32_array - Add a property of 32 bit integers + * property to a changeset + * + * @ocs: changeset pointer + * @np: device node pointer + * @prop_name: name of the property to be added + * @array: pointer to an array of 32 bit integers + * @sz: number of array elements + * + * Create a property of 32 bit integers and add it to a changeset. + * + * Return: 0 on success, a negative error value in case of an error. + */ +int of_changeset_add_prop_u32_array(struct of_changeset *ocs, + struct device_node *np, + const char *prop_name, + const u32 *array, size_t sz) +{ + struct property prop; + __be32 *val; + int i, ret; + + val = kcalloc(sz, sizeof(__be32), GFP_KERNEL); + if (!val) + return -ENOMEM; + + for (i = 0; i < sz; i++) + val[i] = cpu_to_be32(array[i]); + prop.name = (char *)prop_name; + prop.length = sizeof(u32) * sz; + prop.value = (void *)val; + + ret = of_changeset_add_prop_helper(ocs, np, &prop); + kfree(val); + + return ret; +} +EXPORT_SYMBOL_GPL(of_changeset_add_prop_u32_array); diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index ac2d2ba24919..319d2254df9b 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -802,7 +802,9 @@ static void __init of_unittest_changeset(void) struct property *ppname_n21, pname_n21 = { .name = "name", .length = 3, .value = "n21" }; struct property *ppupdate, pupdate = { .name = "prop-update", .length = 5, .value = "abcd" }; struct property *ppremove; - struct device_node *n1, *n2, *n21, *nchangeset, *nremove, *parent, *np; + struct device_node *n1, *n2, *n21, *n22, *nchangeset, *nremove, *parent, *np; + static const char * const str_array[] = { "str1", "str2", "str3" }; + const u32 u32_array[] = { 1, 2, 3 }; struct of_changeset chgset; n1 = __of_node_dup(NULL, "n1"); @@ -857,6 +859,17 @@ static void __init of_unittest_changeset(void) unittest(!of_changeset_add_property(&chgset, parent, ppadd), "fail add prop prop-add\n"); unittest(!of_changeset_update_property(&chgset, parent, ppupdate), "fail update prop\n"); unittest(!of_changeset_remove_property(&chgset, parent, ppremove), "fail remove prop\n"); + n22 = of_changeset_create_node(&chgset, n2, "n22"); + unittest(n22, "fail create n22\n"); + unittest(!of_changeset_add_prop_string(&chgset, n22, "prop-str", "abcd"), + "fail add prop prop-str"); + unittest(!of_changeset_add_prop_string_array(&chgset, n22, "prop-str-array", + (const char **)str_array, + ARRAY_SIZE(str_array)), + "fail add prop prop-str-array"); + unittest(!of_changeset_add_prop_u32_array(&chgset, n22, "prop-u32-array", + u32_array, ARRAY_SIZE(u32_array)), + "fail add prop prop-u32-array"); unittest(!of_changeset_apply(&chgset), "apply failed\n"); @@ -866,6 +879,9 @@ static void __init of_unittest_changeset(void) unittest((np = of_find_node_by_path("/testcase-data/changeset/n2/n21")), "'%pOF' not added\n", n21); of_node_put(np); + unittest((np = of_find_node_by_path("/testcase-data/changeset/n2/n22")), + "'%pOF' not added\n", n22); + of_node_put(np); unittest(!of_changeset_revert(&chgset), "revert failed\n"); @@ -874,6 +890,7 @@ static void __init of_unittest_changeset(void) of_node_put(n1); of_node_put(n2); of_node_put(n21); + of_node_put(n22); #endif } diff --git a/include/linux/of.h b/include/linux/of.h index 7656cc637746..bc2e37f016ec 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -1579,6 +1579,29 @@ static inline int of_changeset_update_property(struct of_changeset *ocs, { return of_changeset_action(ocs, OF_RECONFIG_UPDATE_PROPERTY, np, prop); } + +struct device_node *of_changeset_create_node(struct of_changeset *ocs, + struct device_node *parent, + const char *full_name); +int of_changeset_add_prop_string(struct of_changeset *ocs, + struct device_node *np, + const char *prop_name, const char *str); +int of_changeset_add_prop_string_array(struct of_changeset *ocs, + struct device_node *np, + const char *prop_name, + const char **str_array, size_t sz); +int of_changeset_add_prop_u32_array(struct of_changeset *ocs, + struct device_node *np, + const char *prop_name, + const u32 *array, size_t sz); +static inline int of_changeset_add_prop_u32(struct of_changeset *ocs, + struct device_node *np, + const char *prop_name, + const u32 val) +{ + return of_changeset_add_prop_u32_array(ocs, np, prop_name, &val, 1); +} + #else /* CONFIG_OF_DYNAMIC */ static inline int of_reconfig_notifier_register(struct notifier_block *nb) { -- cgit v1.2.3-58-ga151 From 47284862bfc7fd5672e731e827f43f26bdbd155c Mon Sep 17 00:00:00 2001 From: Lizhi Hou Date: Tue, 15 Aug 2023 10:19:59 -0700 Subject: of: overlay: Extend of_overlay_fdt_apply() to specify the target node Currently, in an overlay fdt fragment, it needs to specify the exact location in base DT. In another word, when the fdt fragment is generated, the base DT location for the fragment is already known. There is new use case that the base DT location is unknown when fdt fragment is generated. For example, the add-on device provide a fdt overlay with its firmware to describe its downstream devices. Because it is add-on device which can be plugged to different systems, its firmware will not be able to know the overlay location in base DT. Instead, the device driver will load the overlay fdt and apply it to base DT at runtime. In this case, of_overlay_fdt_apply() needs to be extended to specify the target node for device driver to apply overlay fdt. int overlay_fdt_apply(..., struct device_node *base); Signed-off-by: Lizhi Hou Link: https://lore.kernel.org/r/1692120000-46900-5-git-send-email-lizhi.hou@amd.com Signed-off-by: Rob Herring --- drivers/of/overlay.c | 42 +++++++++++++++++++++++++++++++----------- drivers/of/unittest.c | 3 ++- include/linux/of.h | 2 +- 3 files changed, 34 insertions(+), 13 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index 7feb643f1370..6f3ae30c878d 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -682,9 +682,11 @@ static int build_changeset(struct overlay_changeset *ovcs) * 1) "target" property containing the phandle of the target * 2) "target-path" property containing the path of the target */ -static struct device_node *find_target(struct device_node *info_node) +static struct device_node *find_target(struct device_node *info_node, + struct device_node *target_base) { struct device_node *node; + char *target_path; const char *path; u32 val; int ret; @@ -700,10 +702,23 @@ static struct device_node *find_target(struct device_node *info_node) ret = of_property_read_string(info_node, "target-path", &path); if (!ret) { - node = of_find_node_by_path(path); - if (!node) - pr_err("find target, node: %pOF, path '%s' not found\n", - info_node, path); + if (target_base) { + target_path = kasprintf(GFP_KERNEL, "%pOF%s", target_base, path); + if (!target_path) + return NULL; + node = of_find_node_by_path(target_path); + if (!node) { + pr_err("find target, node: %pOF, path '%s' not found\n", + info_node, target_path); + } + kfree(target_path); + } else { + node = of_find_node_by_path(path); + if (!node) { + pr_err("find target, node: %pOF, path '%s' not found\n", + info_node, path); + } + } return node; } @@ -715,6 +730,7 @@ static struct device_node *find_target(struct device_node *info_node) /** * init_overlay_changeset() - initialize overlay changeset from overlay tree * @ovcs: Overlay changeset to build + * @target_base: Point to the target node to apply overlay * * Initialize @ovcs. Populate @ovcs->fragments with node information from * the top level of @overlay_root. The relevant top level nodes are the @@ -725,7 +741,8 @@ static struct device_node *find_target(struct device_node *info_node) * detected in @overlay_root. On error return, the caller of * init_overlay_changeset() must call free_overlay_changeset(). */ -static int init_overlay_changeset(struct overlay_changeset *ovcs) +static int init_overlay_changeset(struct overlay_changeset *ovcs, + struct device_node *target_base) { struct device_node *node, *overlay_node; struct fragment *fragment; @@ -786,7 +803,7 @@ static int init_overlay_changeset(struct overlay_changeset *ovcs) fragment = &fragments[cnt]; fragment->overlay = overlay_node; - fragment->target = find_target(node); + fragment->target = find_target(node, target_base); if (!fragment->target) { of_node_put(fragment->overlay); ret = -EINVAL; @@ -877,6 +894,7 @@ static void free_overlay_changeset(struct overlay_changeset *ovcs) * * of_overlay_apply() - Create and apply an overlay changeset * @ovcs: overlay changeset + * @base: point to the target node to apply overlay * * Creates and applies an overlay changeset. * @@ -900,7 +918,8 @@ static void free_overlay_changeset(struct overlay_changeset *ovcs) * the caller of of_overlay_apply() must call free_overlay_changeset(). */ -static int of_overlay_apply(struct overlay_changeset *ovcs) +static int of_overlay_apply(struct overlay_changeset *ovcs, + struct device_node *base) { int ret = 0, ret_revert, ret_tmp; @@ -908,7 +927,7 @@ static int of_overlay_apply(struct overlay_changeset *ovcs) if (ret) goto out; - ret = init_overlay_changeset(ovcs); + ret = init_overlay_changeset(ovcs, base); if (ret) goto out; @@ -952,6 +971,7 @@ out: * @overlay_fdt: pointer to overlay FDT * @overlay_fdt_size: number of bytes in @overlay_fdt * @ret_ovcs_id: pointer for returning created changeset id + * @base: pointer for the target node to apply overlay * * Creates and applies an overlay changeset. * @@ -967,7 +987,7 @@ out: */ int of_overlay_fdt_apply(const void *overlay_fdt, u32 overlay_fdt_size, - int *ret_ovcs_id) + int *ret_ovcs_id, struct device_node *base) { void *new_fdt; void *new_fdt_align; @@ -1037,7 +1057,7 @@ int of_overlay_fdt_apply(const void *overlay_fdt, u32 overlay_fdt_size, } ovcs->overlay_mem = overlay_mem; - ret = of_overlay_apply(ovcs); + ret = of_overlay_apply(ovcs, base); /* * If of_overlay_apply() error, calling free_overlay_changeset() may * result in a memory leak if the apply partly succeeded, so do NOT diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 319d2254df9b..b87dca37b5ec 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -3480,7 +3480,8 @@ static int __init overlay_data_apply(const char *overlay_name, int *ovcs_id) if (!size) pr_err("no overlay data for %s\n", overlay_name); - ret = of_overlay_fdt_apply(info->dtbo_begin, size, &info->ovcs_id); + ret = of_overlay_fdt_apply(info->dtbo_begin, size, &info->ovcs_id, + NULL); if (ovcs_id) *ovcs_id = info->ovcs_id; if (ret < 0) diff --git a/include/linux/of.h b/include/linux/of.h index bc2e37f016ec..ed679819c279 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -1667,7 +1667,7 @@ struct of_overlay_notify_data { #ifdef CONFIG_OF_OVERLAY int of_overlay_fdt_apply(const void *overlay_fdt, u32 overlay_fdt_size, - int *ovcs_id); + int *ovcs_id, struct device_node *target_base); int of_overlay_remove(int *ovcs_id); int of_overlay_remove_all(void); -- cgit v1.2.3-58-ga151 From 26409dd045892904b059dc411403e9c8ce7543ca Mon Sep 17 00:00:00 2001 From: Lizhi Hou Date: Tue, 15 Aug 2023 10:20:00 -0700 Subject: of: unittest: Add pci_dt_testdrv pci driver pci_dt_testdrv is bound to QEMU PCI Test Device. It reads overlay_pci_node fdt fragment and apply it to Test Device. Then it calls of_platform_default_populate() to populate the platform devices. Tested-by: Herve Codina Signed-off-by: Lizhi Hou Link: https://lore.kernel.org/r/1692120000-46900-6-git-send-email-lizhi.hou@amd.com Signed-off-by: Rob Herring --- drivers/of/unittest-data/Makefile | 3 +- drivers/of/unittest-data/overlay_pci_node.dtso | 22 +++ drivers/of/unittest.c | 189 +++++++++++++++++++++++++ drivers/pci/quirks.c | 1 + 4 files changed, 214 insertions(+), 1 deletion(-) create mode 100644 drivers/of/unittest-data/overlay_pci_node.dtso (limited to 'drivers/of') diff --git a/drivers/of/unittest-data/Makefile b/drivers/of/unittest-data/Makefile index ea5f4da68e23..1aa875088159 100644 --- a/drivers/of/unittest-data/Makefile +++ b/drivers/of/unittest-data/Makefile @@ -32,7 +32,8 @@ obj-$(CONFIG_OF_OVERLAY) += overlay.dtbo.o \ overlay_gpio_02b.dtbo.o \ overlay_gpio_03.dtbo.o \ overlay_gpio_04a.dtbo.o \ - overlay_gpio_04b.dtbo.o + overlay_gpio_04b.dtbo.o \ + overlay_pci_node.dtbo.o # enable creation of __symbols__ node DTC_FLAGS_overlay += -@ diff --git a/drivers/of/unittest-data/overlay_pci_node.dtso b/drivers/of/unittest-data/overlay_pci_node.dtso new file mode 100644 index 000000000000..c05e52e9e44a --- /dev/null +++ b/drivers/of/unittest-data/overlay_pci_node.dtso @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/ { + fragment@0 { + target-path=""; + __overlay__ { + #address-cells = <3>; + #size-cells = <2>; + pci-ep-bus@0 { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x0 0x0 0x0 0x1000>; + reg = <0 0 0 0 0>; + unittest-pci@100 { + compatible = "unittest-pci"; + reg = <0x100 0x200>; + }; + }; + }; + }; +}; diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index b87dca37b5ec..939e33afc668 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -3326,6 +3327,7 @@ OVERLAY_INFO_EXTERN(overlay_gpio_02b); OVERLAY_INFO_EXTERN(overlay_gpio_03); OVERLAY_INFO_EXTERN(overlay_gpio_04a); OVERLAY_INFO_EXTERN(overlay_gpio_04b); +OVERLAY_INFO_EXTERN(overlay_pci_node); OVERLAY_INFO_EXTERN(overlay_bad_add_dup_node); OVERLAY_INFO_EXTERN(overlay_bad_add_dup_prop); OVERLAY_INFO_EXTERN(overlay_bad_phandle); @@ -3361,6 +3363,7 @@ static struct overlay_info overlays[] = { OVERLAY_INFO(overlay_gpio_03, 0), OVERLAY_INFO(overlay_gpio_04a, 0), OVERLAY_INFO(overlay_gpio_04b, 0), + OVERLAY_INFO(overlay_pci_node, 0), OVERLAY_INFO(overlay_bad_add_dup_node, -EINVAL), OVERLAY_INFO(overlay_bad_add_dup_prop, -EINVAL), OVERLAY_INFO(overlay_bad_phandle, -EINVAL), @@ -3731,6 +3734,191 @@ static inline __init void of_unittest_overlay_high_level(void) {} #endif +#ifdef CONFIG_PCI_DYNAMIC_OF_NODES + +static int of_unittest_pci_dev_num; +static int of_unittest_pci_child_num; + +/* + * PCI device tree node test driver + */ +static const struct pci_device_id testdrv_pci_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_REDHAT, 0x5), }, /* PCI_VENDOR_ID_REDHAT */ + { 0, } +}; + +static int testdrv_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + struct overlay_info *info; + struct device_node *dn; + int ret, ovcs_id; + u32 size; + + dn = pdev->dev.of_node; + if (!dn) { + dev_err(&pdev->dev, "does not find bus endpoint"); + return -EINVAL; + } + + for (info = overlays; info && info->name; info++) { + if (!strcmp(info->name, "overlay_pci_node")) + break; + } + if (!info || !info->name) { + dev_err(&pdev->dev, "no overlay data for overlay_pci_node"); + return -ENODEV; + } + + size = info->dtbo_end - info->dtbo_begin; + ret = of_overlay_fdt_apply(info->dtbo_begin, size, &ovcs_id, dn); + of_node_put(dn); + if (ret) + return ret; + + of_platform_default_populate(dn, NULL, &pdev->dev); + pci_set_drvdata(pdev, (void *)(uintptr_t)ovcs_id); + + return 0; +} + +static void testdrv_remove(struct pci_dev *pdev) +{ + int ovcs_id = (int)(uintptr_t)pci_get_drvdata(pdev); + + of_platform_depopulate(&pdev->dev); + of_overlay_remove(&ovcs_id); +} + +static struct pci_driver testdrv_driver = { + .name = "pci_dt_testdrv", + .id_table = testdrv_pci_ids, + .probe = testdrv_probe, + .remove = testdrv_remove, +}; + +static int unittest_pci_probe(struct platform_device *pdev) +{ + struct resource *res; + struct device *dev; + u64 exp_addr; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + + dev = &pdev->dev; + while (dev && !dev_is_pci(dev)) + dev = dev->parent; + if (!dev) { + pr_err("unable to find parent device\n"); + return -ENODEV; + } + + exp_addr = pci_resource_start(to_pci_dev(dev), 0) + 0x100; + unittest(res->start == exp_addr, "Incorrect translated address %llx, expected %llx\n", + (u64)res->start, exp_addr); + + of_unittest_pci_child_num++; + + return 0; +} + +static const struct of_device_id unittest_pci_of_match[] = { + { .compatible = "unittest-pci" }, + { } +}; + +static struct platform_driver unittest_pci_driver = { + .probe = unittest_pci_probe, + .driver = { + .name = "unittest-pci", + .of_match_table = unittest_pci_of_match, + }, +}; + +static int of_unittest_pci_node_verify(struct pci_dev *pdev, bool add) +{ + struct device_node *pnp, *np = NULL; + struct device *child_dev; + char *path = NULL; + const __be32 *reg; + int rc = 0; + + pnp = pdev->dev.of_node; + unittest(pnp, "Failed creating PCI dt node\n"); + if (!pnp) + return -ENODEV; + + if (add) { + path = kasprintf(GFP_KERNEL, "%pOF/pci-ep-bus@0/unittest-pci@100", pnp); + np = of_find_node_by_path(path); + unittest(np, "Failed to get unittest-pci node under PCI node\n"); + if (!np) { + rc = -ENODEV; + goto failed; + } + + reg = of_get_property(np, "reg", NULL); + unittest(reg, "Failed to get reg property\n"); + if (!reg) + rc = -ENODEV; + } else { + path = kasprintf(GFP_KERNEL, "%pOF/pci-ep-bus@0", pnp); + np = of_find_node_by_path(path); + unittest(!np, "Child device tree node is not removed\n"); + child_dev = device_find_any_child(&pdev->dev); + unittest(!child_dev, "Child device is not removed\n"); + } + +failed: + kfree(path); + if (np) + of_node_put(np); + + return rc; +} + +static void __init of_unittest_pci_node(void) +{ + struct pci_dev *pdev = NULL; + int rc; + + rc = pci_register_driver(&testdrv_driver); + unittest(!rc, "Failed to register pci test driver; rc = %d\n", rc); + if (rc) + return; + + rc = platform_driver_register(&unittest_pci_driver); + if (unittest(!rc, "Failed to register unittest pci driver\n")) { + pci_unregister_driver(&testdrv_driver); + return; + } + + while ((pdev = pci_get_device(PCI_VENDOR_ID_REDHAT, 0x5, pdev)) != NULL) { + of_unittest_pci_node_verify(pdev, true); + of_unittest_pci_dev_num++; + } + if (pdev) + pci_dev_put(pdev); + + unittest(of_unittest_pci_dev_num, + "No test PCI device been found. Please run QEMU with '-device pci-testdev'\n"); + unittest(of_unittest_pci_dev_num == of_unittest_pci_child_num, + "Child device number %d is not expected %d", of_unittest_pci_child_num, + of_unittest_pci_dev_num); + + platform_driver_unregister(&unittest_pci_driver); + pci_unregister_driver(&testdrv_driver); + + while ((pdev = pci_get_device(PCI_VENDOR_ID_REDHAT, 0x5, pdev)) != NULL) + of_unittest_pci_node_verify(pdev, false); + if (pdev) + pci_dev_put(pdev); +} +#else +static void __init of_unittest_pci_node(void) { } +#endif + static int __init of_unittest(void) { struct device_node *np; @@ -3781,6 +3969,7 @@ static int __init of_unittest(void) of_unittest_platform_populate(); of_unittest_overlay(); of_unittest_lifecycle(); + of_unittest_pci_node(); /* Double check linkage after removing testcase data */ of_unittest_check_tree_linkage(); diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 6c0e7b6bbdd1..a8223ff52939 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -6149,3 +6149,4 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x9a31, dpc_log_size); */ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_XILINX, 0x5020, of_pci_make_dev_node); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_XILINX, 0x5021, of_pci_make_dev_node); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_REDHAT, 0x0005, of_pci_make_dev_node); -- cgit v1.2.3-58-ga151 From 02dfc6acea1ca652cacfc92f4231f058f84f0a73 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 22 Aug 2023 12:22:34 +0200 Subject: of: unittest: Run overlay apply/revert sequence three times Run the test for the overlay apply/revert sequence three times, to test if there are unbalanced of_node_put() calls causing reference counts to become negative. Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/a9fb4eb560c58d11a7f167bc78a137b46e76cf15.1692699743.git.geert+renesas@glider.be Signed-off-by: Rob Herring --- drivers/of/unittest.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/of') diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 939e33afc668..33c20edcc92c 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -3066,6 +3066,7 @@ static void __init of_unittest_overlay_notify(void) static void __init of_unittest_overlay(void) { struct device_node *bus_np = NULL; + unsigned int i; if (platform_driver_register(&unittest_driver)) { unittest(0, "could not register unittest driver\n"); @@ -3103,7 +3104,8 @@ static void __init of_unittest_overlay(void) of_unittest_overlay_2(); of_unittest_overlay_3(); of_unittest_overlay_4(); - of_unittest_overlay_5(); + for (i = 0; i < 3; i++) + of_unittest_overlay_5(); of_unittest_overlay_6(); of_unittest_overlay_8(); -- cgit v1.2.3-58-ga151 From 500d45100aa8546a000eef85bba8c2abc7b36e92 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 1 Aug 2023 11:46:29 -0600 Subject: of: unittest: Check tree matches original after reverting a changeset Enhance the changeset unittest to ensure after a revert, the tree matches the original tree before the changeset was applied. Specifically, check an added node is removed, a removed property is added back, and an updated property has its original value. Signed-off-by: Rob Herring --- drivers/of/unittest.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers/of') diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 33c20edcc92c..064a41007a50 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -797,6 +797,7 @@ static void __init of_unittest_property_copy(void) static void __init of_unittest_changeset(void) { #ifdef CONFIG_OF_DYNAMIC + int ret; struct property *ppadd, padd = { .name = "prop-add", .length = 1, .value = "" }; struct property *ppname_n1, pname_n1 = { .name = "name", .length = 3, .value = "n1" }; struct property *ppname_n2, pname_n2 = { .name = "name", .length = 3, .value = "n2" }; @@ -807,6 +808,7 @@ static void __init of_unittest_changeset(void) static const char * const str_array[] = { "str1", "str2", "str3" }; const u32 u32_array[] = { 1, 2, 3 }; struct of_changeset chgset; + const char *propstr = NULL; n1 = __of_node_dup(NULL, "n1"); unittest(n1, "testcase setup failure\n"); @@ -886,6 +888,17 @@ static void __init of_unittest_changeset(void) unittest(!of_changeset_revert(&chgset), "revert failed\n"); + 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"); + + ret = of_property_read_string(parent, "prop-update", &propstr); + unittest(!ret, "failed to find updated prop after revert\n"); + if (!ret) + unittest(strcmp(propstr, "hello") == 0, "original value not in updated property after revert"); + of_changeset_destroy(&chgset); of_node_put(n1); -- cgit v1.2.3-58-ga151 From a9515ff4fb142b690a0d2b58782b15903b990dba Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 28 Jul 2023 10:50:28 +0200 Subject: of: overlay: Call of_changeset_init() early When of_overlay_fdt_apply() fails, the changeset may be partially applied, and the caller is still expected to call of_overlay_remove() to clean up this partial state. However, of_overlay_apply() calls of_resolve_phandles() before init_overlay_changeset(). Hence if the overlay fails to apply due to an unresolved symbol, the overlay_changeset.cset.entries list is still uninitialized, and cleanup will crash with a NULL-pointer dereference in overlay_removal_is_ok(). Fix this by moving the call to of_changeset_init() from init_overlay_changeset() to of_overlay_fdt_apply(), where all other early initialization is done. Fixes: f948d6d8b792bb90 ("of: overlay: avoid race condition between applying multiple overlays") Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/4f1d6d74b61cba2599026adb6d1948ae559ce91f.1690533838.git.geert+renesas@glider.be Signed-off-by: Rob Herring --- drivers/of/overlay.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/overlay.c b/drivers/of/overlay.c index 6f3ae30c878d..dfb6fb962fc7 100644 --- a/drivers/of/overlay.c +++ b/drivers/of/overlay.c @@ -769,8 +769,6 @@ static int init_overlay_changeset(struct overlay_changeset *ovcs, if (!of_node_is_root(ovcs->overlay_root)) pr_debug("%s() ovcs->overlay_root is not root\n", __func__); - of_changeset_init(&ovcs->cset); - cnt = 0; /* fragment nodes */ @@ -1033,6 +1031,7 @@ int of_overlay_fdt_apply(const void *overlay_fdt, u32 overlay_fdt_size, INIT_LIST_HEAD(&ovcs->ovcs_list); list_add_tail(&ovcs->ovcs_list, &ovcs_list); + of_changeset_init(&ovcs->cset); /* * Must create permanent copy of FDT because of_fdt_unflatten_tree() -- cgit v1.2.3-58-ga151 From 6becf8f845ae1f0b1cfed395bbeccbd23654162d Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 28 Jul 2023 10:50:29 +0200 Subject: of: unittest: Fix overlay type in apply/revert check The removal check in of_unittest_apply_revert_overlay_check() always uses the platform device overlay type, while it should use the actual overlay type, as passed as a parameter to the function. This has no impact on any current test, as all tests calling of_unittest_apply_revert_overlay_check() use the platform device overlay type. Fixes: d5e75500ca401d31 ("of: unitest: Add I2C overlay unit tests.") Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/ba0234c41ba808f10112094f88792beeb6dbaedf.1690533838.git.geert+renesas@glider.be Signed-off-by: Rob Herring --- drivers/of/unittest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/of') diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 064a41007a50..4b6775af3c7e 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -2213,7 +2213,7 @@ static int __init of_unittest_apply_revert_overlay_check(int overlay_nr, of_unittest_untrack_overlay(save_ovcs_id); /* unittest device must be again in before state */ - if (of_unittest_device_exists(unittest_nr, PDEV_OVERLAY) != before) { + if (of_unittest_device_exists(unittest_nr, ovtype) != before) { unittest(0, "%s with device @\"%s\" %s\n", overlay_name_from_nr(overlay_nr), unittest_path(unittest_nr, ovtype), -- cgit v1.2.3-58-ga151 From 8f50c20118ec55b0dd1273b6e789de146d08e579 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 28 Jul 2023 10:50:30 +0200 Subject: of: unittest: Restore indentation in overlay_bad_add_dup_prop test When updating the expected error messages for the overlay_bad_add_dup_prop test, indentation of the EXPECT_END() statements was accidentally changed. Fixes: 29acfb65598f9167 ("of: unittest: kmemleak in duplicate property update") Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/c9bd81b74b0a1ab394ac7ff8819e6fb032fe8ded.1690533838.git.geert+renesas@glider.be Signed-off-by: Rob Herring --- drivers/of/unittest.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 4b6775af3c7e..c01b94a51195 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -3725,11 +3725,11 @@ static __init void of_unittest_overlay_high_level(void) "Adding overlay 'overlay_bad_add_dup_prop' failed\n"); EXPECT_END(KERN_ERR, - "OF: overlay: ERROR: multiple fragments add, update, and/or delete property /testcase-data-2/substation@100/motor-1/electric/name"); + "OF: overlay: ERROR: multiple fragments add, update, and/or delete property /testcase-data-2/substation@100/motor-1/electric/name"); EXPECT_END(KERN_ERR, - "OF: overlay: ERROR: multiple fragments add, update, and/or delete property /testcase-data-2/substation@100/motor-1/electric/rpm_avail"); + "OF: overlay: ERROR: multiple fragments add, update, and/or delete property /testcase-data-2/substation@100/motor-1/electric/rpm_avail"); EXPECT_END(KERN_ERR, - "OF: overlay: ERROR: multiple fragments add and/or delete node /testcase-data-2/substation@100/motor-1/electric"); + "OF: overlay: ERROR: multiple fragments add and/or delete node /testcase-data-2/substation@100/motor-1/electric"); unittest(overlay_data_apply("overlay_bad_phandle", NULL), "Adding overlay 'overlay_bad_phandle' failed\n"); -- cgit v1.2.3-58-ga151 From 35df904df899dba916ceb5248d815bfe71e9367d Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 28 Jul 2023 10:50:31 +0200 Subject: of: unittest: Improve messages and comments in apply/revert checks Miscellaneous improvements for the apply and apply/revert checks, making them more similar: - Fix inverted comment for before state check, - Add more comments to improve symmetry, - Fix grammar s/must be to set to/must be in/, - Avoid saying "create" in messages, as the actual operation depends on the value of the before/after parameters. Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/326ecfe0889c53d2cfff31b3bf950d0b70be225f.1690533838.git.geert+renesas@glider.be Signed-off-by: Rob Herring --- drivers/of/unittest.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index c01b94a51195..35a621e0226c 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -2141,7 +2141,7 @@ static int __init of_unittest_apply_overlay_check(int overlay_nr, { int ret, ovcs_id; - /* unittest device must not be in before state */ + /* unittest device must be in before state */ if (of_unittest_device_exists(unittest_nr, ovtype) != before) { unittest(0, "%s with device @\"%s\" %s\n", overlay_name_from_nr(overlay_nr), @@ -2150,6 +2150,7 @@ static int __init of_unittest_apply_overlay_check(int overlay_nr, return -EINVAL; } + /* apply the overlay */ ovcs_id = 0; ret = of_unittest_apply_overlay(overlay_nr, &ovcs_id); if (ret != 0) { @@ -2157,9 +2158,9 @@ static int __init of_unittest_apply_overlay_check(int overlay_nr, return ret; } - /* unittest device must be to set to after state */ + /* unittest device must be in after state */ if (of_unittest_device_exists(unittest_nr, ovtype) != after) { - unittest(0, "%s failed to create @\"%s\" %s\n", + unittest(0, "%s with device @\"%s\" %s\n", overlay_name_from_nr(overlay_nr), unittest_path(unittest_nr, ovtype), !after ? "enabled" : "disabled"); @@ -2195,13 +2196,14 @@ static int __init of_unittest_apply_revert_overlay_check(int overlay_nr, /* unittest device must be in after state */ if (of_unittest_device_exists(unittest_nr, ovtype) != after) { - unittest(0, "%s failed to create @\"%s\" %s\n", + unittest(0, "%s with device @\"%s\" %s\n", overlay_name_from_nr(overlay_nr), unittest_path(unittest_nr, ovtype), !after ? "enabled" : "disabled"); return -EINVAL; } + /* remove the overlay */ save_ovcs_id = ovcs_id; ret = of_overlay_remove(&ovcs_id); if (ret != 0) { -- cgit v1.2.3-58-ga151 From b7a46e7b44115e186a68a7d95bef5e7d72826304 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 28 Jul 2023 10:50:32 +0200 Subject: of: unittest: Merge of_unittest_apply{,_revert}_overlay_check() of_unittest_apply_overlay_check() and the first part of of_unittest_apply_revert_overlay_check() are identical. Reduce code duplication by replacing them by two wrappers around a common helper. Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/4bafe338655beab6b244047e737c0c2aa60b613d.1690533838.git.geert+renesas@glider.be Signed-off-by: Rob Herring --- drivers/of/unittest.c | 45 ++++++++++++++++++--------------------------- 1 file changed, 18 insertions(+), 27 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 35a621e0226c..57fd7cde5840 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -2134,8 +2134,7 @@ static int __init of_unittest_apply_overlay(int overlay_nr, int *ovcs_id) return 0; } -/* apply an overlay while checking before and after states */ -static int __init of_unittest_apply_overlay_check(int overlay_nr, +static int __init __of_unittest_apply_overlay_check(int overlay_nr, int unittest_nr, int before, int after, enum overlay_type ovtype) { @@ -2167,6 +2166,19 @@ static int __init of_unittest_apply_overlay_check(int overlay_nr, return -EINVAL; } + return ovcs_id; +} + +/* apply an overlay while checking before and after states */ +static int __init of_unittest_apply_overlay_check(int overlay_nr, + int unittest_nr, int before, int after, + enum overlay_type ovtype) +{ + int ovcs_id = __of_unittest_apply_overlay_check(overlay_nr, + unittest_nr, before, after, ovtype); + if (ovcs_id < 0) + return ovcs_id; + return 0; } @@ -2177,31 +2189,10 @@ static int __init of_unittest_apply_revert_overlay_check(int overlay_nr, { int ret, ovcs_id, save_ovcs_id; - /* unittest device must be in before state */ - if (of_unittest_device_exists(unittest_nr, ovtype) != before) { - unittest(0, "%s with device @\"%s\" %s\n", - overlay_name_from_nr(overlay_nr), - unittest_path(unittest_nr, ovtype), - !before ? "enabled" : "disabled"); - return -EINVAL; - } - - /* apply the overlay */ - ovcs_id = 0; - ret = of_unittest_apply_overlay(overlay_nr, &ovcs_id); - if (ret != 0) { - /* of_unittest_apply_overlay already called unittest() */ - return ret; - } - - /* unittest device must be in after state */ - if (of_unittest_device_exists(unittest_nr, ovtype) != after) { - unittest(0, "%s with device @\"%s\" %s\n", - overlay_name_from_nr(overlay_nr), - unittest_path(unittest_nr, ovtype), - !after ? "enabled" : "disabled"); - return -EINVAL; - } + ovcs_id = __of_unittest_apply_overlay_check(overlay_nr, unittest_nr, + before, after, ovtype); + if (ovcs_id < 0) + return ovcs_id; /* remove the overlay */ save_ovcs_id = ovcs_id; -- cgit v1.2.3-58-ga151 From 0676aeeca537740a03ecdb8b699b37e98ec60289 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 28 Jul 2023 10:50:33 +0200 Subject: of: unittest: Cleanup partially-applied overlays When of_overlay_fdt_apply() fails, the changeset may be partially applied, and the caller is still expected to call of_overlay_remove() to clean up this partial state. However, overlay_17 is the only test that takes care of cleaning up after an (expected) failure. Instead of adding cleanup code to each individual test, extend overlay_info with the optional expected return value of of_overlay_remove(), and handle cleanup in the overlay_data_apply() helper. While at it, simplify the end marker in the overlay_info table. Update the expected error output for errors during the newly cleanup. Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/594a6a8934e5569bf96d317a6a3c0a9129a2ae20.1690533838.git.geert+renesas@glider.be [robh: update and fix EXPECT messages] Signed-off-by: Rob Herring --- drivers/of/unittest.c | 132 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 84 insertions(+), 48 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 57fd7cde5840..f450c434a403 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -2997,12 +2997,6 @@ static void __init of_unittest_overlay_notify(void) unittest(ovcs_id, "ovcs_id not created for overlay_17\n"); - if (ovcs_id) { - ret = of_overlay_remove(&ovcs_id); - unittest(!ret, - "overlay_17 of_overlay_remove(), ret = %d\n", ret); - } - /* --- overlay 18 --- */ unittest(overlay_data_apply("overlay_18", &ovcs_id), @@ -3292,17 +3286,19 @@ out_skip_tests: extern uint8_t __dtbo_##overlay_name##_begin[]; \ extern uint8_t __dtbo_##overlay_name##_end[] -#define OVERLAY_INFO(overlay_name, expected) \ -{ .dtbo_begin = __dtbo_##overlay_name##_begin, \ - .dtbo_end = __dtbo_##overlay_name##_end, \ - .expected_result = expected, \ - .name = #overlay_name, \ +#define OVERLAY_INFO(overlay_name, expected, expected_remove) \ +{ .dtbo_begin = __dtbo_##overlay_name##_begin, \ + .dtbo_end = __dtbo_##overlay_name##_end, \ + .expected_result = expected, \ + .expected_result_remove = expected_remove, \ + .name = #overlay_name, \ } struct overlay_info { uint8_t *dtbo_begin; uint8_t *dtbo_end; int expected_result; + int expected_result_remove; /* if apply failed */ int ovcs_id; char *name; }; @@ -3343,41 +3339,41 @@ OVERLAY_INFO_EXTERN(overlay_bad_symbol); /* entries found by name */ static struct overlay_info overlays[] = { - OVERLAY_INFO(overlay_base, -9999), - OVERLAY_INFO(overlay, 0), - OVERLAY_INFO(overlay_0, 0), - OVERLAY_INFO(overlay_1, 0), - OVERLAY_INFO(overlay_2, 0), - OVERLAY_INFO(overlay_3, 0), - OVERLAY_INFO(overlay_4, 0), - OVERLAY_INFO(overlay_5, 0), - OVERLAY_INFO(overlay_6, 0), - OVERLAY_INFO(overlay_7, 0), - OVERLAY_INFO(overlay_8, 0), - OVERLAY_INFO(overlay_9, 0), - OVERLAY_INFO(overlay_10, 0), - OVERLAY_INFO(overlay_11, 0), - OVERLAY_INFO(overlay_12, 0), - OVERLAY_INFO(overlay_13, 0), - OVERLAY_INFO(overlay_15, 0), - OVERLAY_INFO(overlay_16, -EBUSY), - OVERLAY_INFO(overlay_17, -EEXIST), - OVERLAY_INFO(overlay_18, 0), - OVERLAY_INFO(overlay_19, 0), - OVERLAY_INFO(overlay_20, 0), - OVERLAY_INFO(overlay_gpio_01, 0), - OVERLAY_INFO(overlay_gpio_02a, 0), - OVERLAY_INFO(overlay_gpio_02b, 0), - OVERLAY_INFO(overlay_gpio_03, 0), - OVERLAY_INFO(overlay_gpio_04a, 0), - OVERLAY_INFO(overlay_gpio_04b, 0), - OVERLAY_INFO(overlay_pci_node, 0), - OVERLAY_INFO(overlay_bad_add_dup_node, -EINVAL), - OVERLAY_INFO(overlay_bad_add_dup_prop, -EINVAL), - OVERLAY_INFO(overlay_bad_phandle, -EINVAL), - OVERLAY_INFO(overlay_bad_symbol, -EINVAL), + OVERLAY_INFO(overlay_base, -9999, 0), + OVERLAY_INFO(overlay, 0, 0), + OVERLAY_INFO(overlay_0, 0, 0), + OVERLAY_INFO(overlay_1, 0, 0), + OVERLAY_INFO(overlay_2, 0, 0), + OVERLAY_INFO(overlay_3, 0, 0), + OVERLAY_INFO(overlay_4, 0, 0), + OVERLAY_INFO(overlay_5, 0, 0), + OVERLAY_INFO(overlay_6, 0, 0), + OVERLAY_INFO(overlay_7, 0, 0), + OVERLAY_INFO(overlay_8, 0, 0), + OVERLAY_INFO(overlay_9, 0, 0), + OVERLAY_INFO(overlay_10, 0, 0), + OVERLAY_INFO(overlay_11, 0, 0), + OVERLAY_INFO(overlay_12, 0, 0), + OVERLAY_INFO(overlay_13, 0, 0), + OVERLAY_INFO(overlay_15, 0, 0), + OVERLAY_INFO(overlay_16, -EBUSY, 0), + OVERLAY_INFO(overlay_17, -EEXIST, 0), + OVERLAY_INFO(overlay_18, 0, 0), + OVERLAY_INFO(overlay_19, 0, 0), + OVERLAY_INFO(overlay_20, 0, 0), + OVERLAY_INFO(overlay_gpio_01, 0, 0), + OVERLAY_INFO(overlay_gpio_02a, 0, 0), + OVERLAY_INFO(overlay_gpio_02b, 0, 0), + OVERLAY_INFO(overlay_gpio_03, 0, 0), + OVERLAY_INFO(overlay_gpio_04a, 0, 0), + OVERLAY_INFO(overlay_gpio_04b, 0, 0), + OVERLAY_INFO(overlay_pci_node, 0, 0), + OVERLAY_INFO(overlay_bad_add_dup_node, -EINVAL, -ENODEV), + OVERLAY_INFO(overlay_bad_add_dup_prop, -EINVAL, -ENODEV), + OVERLAY_INFO(overlay_bad_phandle, -EINVAL, 0), + OVERLAY_INFO(overlay_bad_symbol, -EINVAL, -ENODEV), /* end marker */ - {.dtbo_begin = NULL, .dtbo_end = NULL, .expected_result = 0, .name = NULL} + { } }; static struct device_node *overlay_base_root; @@ -3472,8 +3468,9 @@ void __init unittest_unflatten_overlay_base(void) static int __init overlay_data_apply(const char *overlay_name, int *ovcs_id) { struct overlay_info *info; + int passed = 1; int found = 0; - int ret; + int ret, ret2; u32 size; for (info = overlays; info && info->name; info++) { @@ -3501,11 +3498,24 @@ static int __init overlay_data_apply(const char *overlay_name, int *ovcs_id) pr_debug("%s applied\n", overlay_name); out: - if (ret != info->expected_result) + if (ret != info->expected_result) { pr_err("of_overlay_fdt_apply() expected %d, ret=%d, %s\n", info->expected_result, ret, overlay_name); + passed = 0; + } + + if (ret < 0) { + /* changeset may be partially applied */ + ret2 = of_overlay_remove(&info->ovcs_id); + if (ret2 != info->expected_result_remove) { + pr_err("of_overlay_remove() expected %d, ret=%d, %s\n", + info->expected_result_remove, ret2, + overlay_name); + passed = 0; + } + } - return (ret == info->expected_result); + return passed; } /* @@ -3698,10 +3708,18 @@ static __init void of_unittest_overlay_high_level(void) "OF: overlay: ERROR: multiple fragments add and/or delete node /testcase-data-2/substation@100/motor-1/controller"); EXPECT_BEGIN(KERN_ERR, "OF: overlay: ERROR: multiple fragments add, update, and/or delete property /testcase-data-2/substation@100/motor-1/controller/name"); + EXPECT_BEGIN(KERN_ERR, + "OF: changeset: apply failed: REMOVE_PROPERTY /testcase-data-2/substation@100/motor-1/controller:name"); + EXPECT_BEGIN(KERN_ERR, + "OF: Error reverting changeset (-19)"); unittest(overlay_data_apply("overlay_bad_add_dup_node", NULL), "Adding overlay 'overlay_bad_add_dup_node' failed\n"); + EXPECT_END(KERN_ERR, + "OF: Error reverting changeset (-19)"); + EXPECT_END(KERN_ERR, + "OF: changeset: apply failed: REMOVE_PROPERTY /testcase-data-2/substation@100/motor-1/controller:name"); EXPECT_END(KERN_ERR, "OF: overlay: ERROR: multiple fragments add, update, and/or delete property /testcase-data-2/substation@100/motor-1/controller/name"); EXPECT_END(KERN_ERR, @@ -3713,10 +3731,18 @@ static __init void of_unittest_overlay_high_level(void) "OF: overlay: ERROR: multiple fragments add, update, and/or delete property /testcase-data-2/substation@100/motor-1/electric/rpm_avail"); EXPECT_BEGIN(KERN_ERR, "OF: overlay: ERROR: multiple fragments add, update, and/or delete property /testcase-data-2/substation@100/motor-1/electric/name"); + EXPECT_BEGIN(KERN_ERR, + "OF: changeset: apply failed: REMOVE_PROPERTY /testcase-data-2/substation@100/motor-1/electric:name"); + EXPECT_BEGIN(KERN_ERR, + "OF: Error reverting changeset (-19)"); unittest(overlay_data_apply("overlay_bad_add_dup_prop", NULL), "Adding overlay 'overlay_bad_add_dup_prop' failed\n"); + EXPECT_END(KERN_ERR, + "OF: Error reverting changeset (-19)"); + EXPECT_END(KERN_ERR, + "OF: changeset: apply failed: REMOVE_PROPERTY /testcase-data-2/substation@100/motor-1/electric:name"); EXPECT_END(KERN_ERR, "OF: overlay: ERROR: multiple fragments add, update, and/or delete property /testcase-data-2/substation@100/motor-1/electric/name"); EXPECT_END(KERN_ERR, @@ -3727,9 +3753,19 @@ static __init void of_unittest_overlay_high_level(void) unittest(overlay_data_apply("overlay_bad_phandle", NULL), "Adding overlay 'overlay_bad_phandle' failed\n"); + EXPECT_BEGIN(KERN_ERR, + "OF: changeset: apply failed: REMOVE_PROPERTY /testcase-data-2/substation@100/hvac-medium-2:name"); + EXPECT_BEGIN(KERN_ERR, + "OF: Error reverting changeset (-19)"); + unittest(overlay_data_apply("overlay_bad_symbol", NULL), "Adding overlay 'overlay_bad_symbol' failed\n"); + EXPECT_END(KERN_ERR, + "OF: Error reverting changeset (-19)"); + EXPECT_END(KERN_ERR, + "OF: changeset: apply failed: REMOVE_PROPERTY /testcase-data-2/substation@100/hvac-medium-2:name"); + return; err_unlock: -- cgit v1.2.3-58-ga151 From ee32072fd12561b6f5fdf96fef7cf6acc323b564 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 28 Jul 2023 10:50:34 +0200 Subject: of: unittest: Add separators to of_unittest_overlay_high_level() It is hard to see the start and end of each individual test in of_unittest_overlay_high_level(). Add visual cues in the form of separator comments, like was done in of_unittest_overlay_notify(). Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/84530100a54a1fac932008057746015e65bc4d9a.1690533838.git.geert+renesas@glider.be Signed-off-by: Rob Herring --- drivers/of/unittest.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers/of') diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index f450c434a403..18ccfdc3dd89 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -3654,6 +3654,8 @@ static __init void of_unittest_overlay_high_level(void) /* now do the normal overlay usage test */ + /* --- overlay --- */ + EXPECT_BEGIN(KERN_ERR, "OF: overlay: WARNING: memory leak will occur if overlay removed, property: /testcase-data-2/substation@100/status"); EXPECT_BEGIN(KERN_ERR, @@ -3704,6 +3706,8 @@ static __init void of_unittest_overlay_high_level(void) unittest(ret, "Adding overlay 'overlay' failed\n"); + /* --- overlay_bad_add_dup_node --- */ + EXPECT_BEGIN(KERN_ERR, "OF: overlay: ERROR: multiple fragments add and/or delete node /testcase-data-2/substation@100/motor-1/controller"); EXPECT_BEGIN(KERN_ERR, @@ -3725,6 +3729,8 @@ static __init void of_unittest_overlay_high_level(void) EXPECT_END(KERN_ERR, "OF: overlay: ERROR: multiple fragments add and/or delete node /testcase-data-2/substation@100/motor-1/controller"); + /* --- overlay_bad_add_dup_prop --- */ + EXPECT_BEGIN(KERN_ERR, "OF: overlay: ERROR: multiple fragments add and/or delete node /testcase-data-2/substation@100/motor-1/electric"); EXPECT_BEGIN(KERN_ERR, @@ -3750,9 +3756,13 @@ static __init void of_unittest_overlay_high_level(void) EXPECT_END(KERN_ERR, "OF: overlay: ERROR: multiple fragments add and/or delete node /testcase-data-2/substation@100/motor-1/electric"); + /* --- overlay_bad_phandle --- */ + unittest(overlay_data_apply("overlay_bad_phandle", NULL), "Adding overlay 'overlay_bad_phandle' failed\n"); + /* --- overlay_bad_symbol --- */ + EXPECT_BEGIN(KERN_ERR, "OF: changeset: apply failed: REMOVE_PROPERTY /testcase-data-2/substation@100/hvac-medium-2:name"); EXPECT_BEGIN(KERN_ERR, -- cgit v1.2.3-58-ga151 From eb38b9529aefa344cbfde25a274c2b6f2931648b Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 28 Jul 2023 10:50:35 +0200 Subject: of: overlay: unittest: Add test for unresolved symbol Add a test to exercise the error paths when trying to apply an overlay with an unresolved symbol and cleaning up the resulting partial state. Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/580394587976975770c84411896fce9fbbcf25fa.1690533838.git.geert+renesas@glider.be Signed-off-by: Rob Herring --- drivers/of/unittest-data/Makefile | 3 ++- drivers/of/unittest-data/overlay_bad_unresolved.dtso | 7 +++++++ drivers/of/unittest.c | 17 +++++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 drivers/of/unittest-data/overlay_bad_unresolved.dtso (limited to 'drivers/of') diff --git a/drivers/of/unittest-data/Makefile b/drivers/of/unittest-data/Makefile index 1aa875088159..01a966e39f23 100644 --- a/drivers/of/unittest-data/Makefile +++ b/drivers/of/unittest-data/Makefile @@ -33,7 +33,8 @@ obj-$(CONFIG_OF_OVERLAY) += overlay.dtbo.o \ overlay_gpio_03.dtbo.o \ overlay_gpio_04a.dtbo.o \ overlay_gpio_04b.dtbo.o \ - overlay_pci_node.dtbo.o + overlay_pci_node.dtbo.o \ + overlay_bad_unresolved.dtbo.o # enable creation of __symbols__ node DTC_FLAGS_overlay += -@ diff --git a/drivers/of/unittest-data/overlay_bad_unresolved.dtso b/drivers/of/unittest-data/overlay_bad_unresolved.dtso new file mode 100644 index 000000000000..3b75a53ae8a4 --- /dev/null +++ b/drivers/of/unittest-data/overlay_bad_unresolved.dtso @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; +/plugin/; + +&this_label_does_not_exist { + status = "ok"; +}; diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 18ccfdc3dd89..9c0f352cb241 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -3336,6 +3336,7 @@ OVERLAY_INFO_EXTERN(overlay_bad_add_dup_node); OVERLAY_INFO_EXTERN(overlay_bad_add_dup_prop); OVERLAY_INFO_EXTERN(overlay_bad_phandle); OVERLAY_INFO_EXTERN(overlay_bad_symbol); +OVERLAY_INFO_EXTERN(overlay_bad_unresolved); /* entries found by name */ static struct overlay_info overlays[] = { @@ -3372,6 +3373,7 @@ static struct overlay_info overlays[] = { OVERLAY_INFO(overlay_bad_add_dup_prop, -EINVAL, -ENODEV), OVERLAY_INFO(overlay_bad_phandle, -EINVAL, 0), OVERLAY_INFO(overlay_bad_symbol, -EINVAL, -ENODEV), + OVERLAY_INFO(overlay_bad_unresolved, -EINVAL, 0), /* end marker */ { } }; @@ -3776,6 +3778,21 @@ static __init void of_unittest_overlay_high_level(void) EXPECT_END(KERN_ERR, "OF: changeset: apply failed: REMOVE_PROPERTY /testcase-data-2/substation@100/hvac-medium-2:name"); + /* --- overlay_bad_unresolved --- */ + + EXPECT_BEGIN(KERN_ERR, + "OF: resolver: node label 'this_label_does_not_exist' not found in live devicetree symbols table"); + EXPECT_BEGIN(KERN_ERR, + "OF: resolver: overlay phandle fixup failed: -22"); + + unittest(overlay_data_apply("overlay_bad_unresolved", NULL), + "Adding overlay 'overlay_bad_unresolved' failed\n"); + + EXPECT_END(KERN_ERR, + "OF: resolver: overlay phandle fixup failed: -22"); + EXPECT_END(KERN_ERR, + "OF: resolver: node label 'this_label_does_not_exist' not found in live devicetree symbols table"); + return; err_unlock: -- cgit v1.2.3-58-ga151 From 121b83eaddde76cf5c49f9b4bd5b1b67c77b1c88 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 28 Jul 2023 10:50:36 +0200 Subject: of: unittest-data: Convert remaining overlay DTS files to sugar syntax Overlay syntactic sugar for generating target-path fragments is supported by the version of dtc supplied with the kernel since commit 50aafd60898a8b3e ("scripts/dtc: Update to upstream version v1.4.6-21-g84e414b0b5bc"). Hence convert the remaining unittest overlay devicetree source files to sugar syntax, improving readability. This completes the work started in commit db2f3762d609318e ("of: convert unittest overlay devicetree source to sugar syntax"). Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/9b5991c85e5a2a7cdf33a4e59b42ef98eaadd98a.1690533838.git.geert+renesas@glider.be Signed-off-by: Rob Herring --- drivers/of/unittest-data/overlay_0.dtso | 11 +++-------- drivers/of/unittest-data/overlay_1.dtso | 11 +++-------- drivers/of/unittest-data/overlay_12.dtso | 11 +++-------- drivers/of/unittest-data/overlay_13.dtso | 11 +++-------- 4 files changed, 12 insertions(+), 32 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/unittest-data/overlay_0.dtso b/drivers/of/unittest-data/overlay_0.dtso index ac0f9e0fe65f..bb46582e0485 100644 --- a/drivers/of/unittest-data/overlay_0.dtso +++ b/drivers/of/unittest-data/overlay_0.dtso @@ -2,13 +2,8 @@ /dts-v1/; /plugin/; -/ { - /* overlay_0 - enable using absolute target path */ +/* overlay_0 - enable using absolute target path */ - fragment@0 { - target-path = "/testcase-data/overlay-node/test-bus/test-unittest0"; - __overlay__ { - status = "okay"; - }; - }; +&{/testcase-data/overlay-node/test-bus/test-unittest0} { + status = "okay"; }; diff --git a/drivers/of/unittest-data/overlay_1.dtso b/drivers/of/unittest-data/overlay_1.dtso index e92a626e2948..9c0fc8ffa4a1 100644 --- a/drivers/of/unittest-data/overlay_1.dtso +++ b/drivers/of/unittest-data/overlay_1.dtso @@ -2,13 +2,8 @@ /dts-v1/; /plugin/; -/ { - /* overlay_1 - disable using absolute target path */ +/* overlay_1 - disable using absolute target path */ - fragment@0 { - target-path = "/testcase-data/overlay-node/test-bus/test-unittest1"; - __overlay__ { - status = "disabled"; - }; - }; +&{/testcase-data/overlay-node/test-bus/test-unittest1} { + status = "disabled"; }; diff --git a/drivers/of/unittest-data/overlay_12.dtso b/drivers/of/unittest-data/overlay_12.dtso index ca3441e2cbec..8d5087793eb4 100644 --- a/drivers/of/unittest-data/overlay_12.dtso +++ b/drivers/of/unittest-data/overlay_12.dtso @@ -2,13 +2,8 @@ /dts-v1/; /plugin/; -/ { - /* overlay_12 - enable using absolute target path (i2c) */ +/* overlay_12 - enable using absolute target path (i2c) */ - fragment@0 { - target-path = "/testcase-data/overlay-node/test-bus/i2c-test-bus/test-unittest12"; - __overlay__ { - status = "okay"; - }; - }; +&{/testcase-data/overlay-node/test-bus/i2c-test-bus/test-unittest12} { + status = "okay"; }; diff --git a/drivers/of/unittest-data/overlay_13.dtso b/drivers/of/unittest-data/overlay_13.dtso index 3c30dec63894..da200ae94f45 100644 --- a/drivers/of/unittest-data/overlay_13.dtso +++ b/drivers/of/unittest-data/overlay_13.dtso @@ -2,13 +2,8 @@ /dts-v1/; /plugin/; -/ { - /* overlay_13 - disable using absolute target path (i2c) */ +/* overlay_13 - disable using absolute target path (i2c) */ - fragment@0 { - target-path = "/testcase-data/overlay-node/test-bus/i2c-test-bus/test-unittest13"; - __overlay__ { - status = "disabled"; - }; - }; +&{/testcase-data/overlay-node/test-bus/i2c-test-bus/test-unittest13} { + status = "disabled"; }; -- cgit v1.2.3-58-ga151 From 517dba9711f9c872d5c607d6ac69b90947e0d8be Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 28 Jul 2023 10:50:37 +0200 Subject: of: unittest-data: Fix whitespace - blank lines Blank line between properties and subnodes. Blank line between subsequent subnodes. No blank line after subnode opening curly brace. No blank line after subnode closing curly brace. No blank line at end of file. Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/c8a512947b22ac95f2ba40e843ecf6015814312e.1690533838.git.geert+renesas@glider.be Signed-off-by: Rob Herring --- drivers/of/unittest-data/overlay.dtso | 2 -- drivers/of/unittest-data/overlay_11.dtso | 1 - drivers/of/unittest-data/overlay_15.dtso | 1 + drivers/of/unittest-data/overlay_4.dtso | 1 - drivers/of/unittest-data/overlay_bad_add_dup_node.dtso | 1 - drivers/of/unittest-data/overlay_bad_add_dup_prop.dtso | 1 - drivers/of/unittest-data/overlay_bad_phandle.dtso | 1 - drivers/of/unittest-data/overlay_bad_symbol.dtso | 1 - drivers/of/unittest-data/overlay_common.dtsi | 2 -- drivers/of/unittest-data/overlay_gpio_01.dtso | 1 + drivers/of/unittest-data/overlay_gpio_02a.dtso | 1 + drivers/of/unittest-data/overlay_gpio_02b.dtso | 1 + drivers/of/unittest-data/overlay_gpio_03.dtso | 1 + drivers/of/unittest-data/overlay_gpio_04a.dtso | 1 + drivers/of/unittest-data/overlay_gpio_04b.dtso | 1 + drivers/of/unittest-data/testcases_common.dtsi | 1 + drivers/of/unittest-data/tests-interrupts.dtsi | 1 + drivers/of/unittest-data/tests-overlay.dtsi | 1 - drivers/of/unittest-data/tests-phandle.dtsi | 2 ++ 19 files changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/unittest-data/overlay.dtso b/drivers/of/unittest-data/overlay.dtso index 3bbc59e922fe..0c078b08ef08 100644 --- a/drivers/of/unittest-data/overlay.dtso +++ b/drivers/of/unittest-data/overlay.dtso @@ -3,7 +3,6 @@ /plugin/; &electric_1 { - status = "okay"; hvac_2: hvac-large-1 { @@ -57,7 +56,6 @@ }; &lights_2 { - status = "okay"; color = "purple", "white", "red", "green"; rate = < 3 256 >; diff --git a/drivers/of/unittest-data/overlay_11.dtso b/drivers/of/unittest-data/overlay_11.dtso index 9a79b253a809..7d04ff503a18 100644 --- a/drivers/of/unittest-data/overlay_11.dtso +++ b/drivers/of/unittest-data/overlay_11.dtso @@ -23,6 +23,5 @@ status = "okay"; reg = <1>; }; - }; }; diff --git a/drivers/of/unittest-data/overlay_15.dtso b/drivers/of/unittest-data/overlay_15.dtso index 5728490474f6..ba02ae1fed38 100644 --- a/drivers/of/unittest-data/overlay_15.dtso +++ b/drivers/of/unittest-data/overlay_15.dtso @@ -7,6 +7,7 @@ &unittest_i2c_test_bus { #address-cells = <1>; #size-cells = <0>; + test-unittest15 { reg = <11>; compatible = "unittest-i2c-mux"; diff --git a/drivers/of/unittest-data/overlay_4.dtso b/drivers/of/unittest-data/overlay_4.dtso index a8a77ddf9abe..9b9eadddb4a0 100644 --- a/drivers/of/unittest-data/overlay_4.dtso +++ b/drivers/of/unittest-data/overlay_4.dtso @@ -5,7 +5,6 @@ /* overlay_4 - test insertion of a full node */ &unittest_test_bus { - /* suppress DTC warning */ #address-cells = <1>; #size-cells = <0>; diff --git a/drivers/of/unittest-data/overlay_bad_add_dup_node.dtso b/drivers/of/unittest-data/overlay_bad_add_dup_node.dtso index 145dfc3b1024..a8d8534f725c 100644 --- a/drivers/of/unittest-data/overlay_bad_add_dup_node.dtso +++ b/drivers/of/unittest-data/overlay_bad_add_dup_node.dtso @@ -13,7 +13,6 @@ */ &electric_1 { - motor-1 { controller { power_bus = < 0x1 0x2 >; diff --git a/drivers/of/unittest-data/overlay_bad_add_dup_prop.dtso b/drivers/of/unittest-data/overlay_bad_add_dup_prop.dtso index 6327d1ffb963..3f0ee9cbefb8 100644 --- a/drivers/of/unittest-data/overlay_bad_add_dup_prop.dtso +++ b/drivers/of/unittest-data/overlay_bad_add_dup_prop.dtso @@ -24,7 +24,6 @@ */ &electric_1 { - motor-1 { electric { rpm_avail = < 100 >; diff --git a/drivers/of/unittest-data/overlay_bad_phandle.dtso b/drivers/of/unittest-data/overlay_bad_phandle.dtso index 83b797360318..ab2c7df10196 100644 --- a/drivers/of/unittest-data/overlay_bad_phandle.dtso +++ b/drivers/of/unittest-data/overlay_bad_phandle.dtso @@ -3,7 +3,6 @@ /plugin/; &electric_1 { - // This label should cause an error when the overlay // is applied. There is already a phandle value // in the base tree for motor-1. diff --git a/drivers/of/unittest-data/overlay_bad_symbol.dtso b/drivers/of/unittest-data/overlay_bad_symbol.dtso index 98c6d1de144a..5d4e34baf1d8 100644 --- a/drivers/of/unittest-data/overlay_bad_symbol.dtso +++ b/drivers/of/unittest-data/overlay_bad_symbol.dtso @@ -3,7 +3,6 @@ /plugin/; &electric_1 { - // This label should cause an error when the overlay // is applied. There is already a symbol hvac_1 // in the base tree diff --git a/drivers/of/unittest-data/overlay_common.dtsi b/drivers/of/unittest-data/overlay_common.dtsi index 08874a72556e..491b89c43cf3 100644 --- a/drivers/of/unittest-data/overlay_common.dtsi +++ b/drivers/of/unittest-data/overlay_common.dtsi @@ -85,7 +85,5 @@ compatible = "ot,tickets"; status = "disabled"; }; - }; }; - diff --git a/drivers/of/unittest-data/overlay_gpio_01.dtso b/drivers/of/unittest-data/overlay_gpio_01.dtso index 699ff104ae10..bb3a31a2137a 100644 --- a/drivers/of/unittest-data/overlay_gpio_01.dtso +++ b/drivers/of/unittest-data/overlay_gpio_01.dtso @@ -5,6 +5,7 @@ &unittest_test_bus { #address-cells = <1>; #size-cells = <0>; + gpio@0 { compatible = "unittest-gpio"; reg = <0>; diff --git a/drivers/of/unittest-data/overlay_gpio_02a.dtso b/drivers/of/unittest-data/overlay_gpio_02a.dtso index ec59aff6ed47..da955537df74 100644 --- a/drivers/of/unittest-data/overlay_gpio_02a.dtso +++ b/drivers/of/unittest-data/overlay_gpio_02a.dtso @@ -5,6 +5,7 @@ &unittest_test_bus { #address-cells = <1>; #size-cells = <0>; + gpio@2 { compatible = "unittest-gpio"; reg = <2>; diff --git a/drivers/of/unittest-data/overlay_gpio_02b.dtso b/drivers/of/unittest-data/overlay_gpio_02b.dtso index 43ce111d41ce..79503965d3d7 100644 --- a/drivers/of/unittest-data/overlay_gpio_02b.dtso +++ b/drivers/of/unittest-data/overlay_gpio_02b.dtso @@ -5,6 +5,7 @@ &unittest_test_bus { #address-cells = <1>; #size-cells = <0>; + gpio@2 { line-a { gpio-hog; diff --git a/drivers/of/unittest-data/overlay_gpio_03.dtso b/drivers/of/unittest-data/overlay_gpio_03.dtso index 6e0312340a1b..d8c709616029 100644 --- a/drivers/of/unittest-data/overlay_gpio_03.dtso +++ b/drivers/of/unittest-data/overlay_gpio_03.dtso @@ -5,6 +5,7 @@ &unittest_test_bus { #address-cells = <1>; #size-cells = <0>; + gpio@3 { compatible = "unittest-gpio"; reg = <3>; diff --git a/drivers/of/unittest-data/overlay_gpio_04a.dtso b/drivers/of/unittest-data/overlay_gpio_04a.dtso index 7b1e04ebfa7a..de86511972c2 100644 --- a/drivers/of/unittest-data/overlay_gpio_04a.dtso +++ b/drivers/of/unittest-data/overlay_gpio_04a.dtso @@ -5,6 +5,7 @@ &unittest_test_bus { #address-cells = <1>; #size-cells = <0>; + gpio@4 { compatible = "unittest-gpio"; reg = <4>; diff --git a/drivers/of/unittest-data/overlay_gpio_04b.dtso b/drivers/of/unittest-data/overlay_gpio_04b.dtso index a14e95c6699a..dc6eff22f927 100644 --- a/drivers/of/unittest-data/overlay_gpio_04b.dtso +++ b/drivers/of/unittest-data/overlay_gpio_04b.dtso @@ -5,6 +5,7 @@ &unittest_test_bus { #address-cells = <1>; #size-cells = <0>; + gpio@4 { line-c { gpio-hog; diff --git a/drivers/of/unittest-data/testcases_common.dtsi b/drivers/of/unittest-data/testcases_common.dtsi index e7887f2301c1..1c2cdf353ae3 100644 --- a/drivers/of/unittest-data/testcases_common.dtsi +++ b/drivers/of/unittest-data/testcases_common.dtsi @@ -5,6 +5,7 @@ changeset { prop-update = "hello"; prop-remove = "world"; + node-remove { }; }; diff --git a/drivers/of/unittest-data/tests-interrupts.dtsi b/drivers/of/unittest-data/tests-interrupts.dtsi index ecc74dbcc373..7c9f31cc131b 100644 --- a/drivers/of/unittest-data/tests-interrupts.dtsi +++ b/drivers/of/unittest-data/tests-interrupts.dtsi @@ -5,6 +5,7 @@ interrupts { #address-cells = <1>; #size-cells = <1>; + test_intc0: intc0 { interrupt-controller; #interrupt-cells = <1>; diff --git a/drivers/of/unittest-data/tests-overlay.dtsi b/drivers/of/unittest-data/tests-overlay.dtsi index 4ea024d908ee..eb35e8aa5d5a 100644 --- a/drivers/of/unittest-data/tests-overlay.dtsi +++ b/drivers/of/unittest-data/tests-overlay.dtsi @@ -3,7 +3,6 @@ / { testcase-data { overlay-node { - /* test bus */ unittest_test_bus: test-bus { compatible = "simple-bus"; diff --git a/drivers/of/unittest-data/tests-phandle.dtsi b/drivers/of/unittest-data/tests-phandle.dtsi index 6b33be4c4416..d01f92f0f0db 100644 --- a/drivers/of/unittest-data/tests-phandle.dtsi +++ b/drivers/of/unittest-data/tests-phandle.dtsi @@ -8,7 +8,9 @@ testcase: testcase-data { security-password = "password"; duplicate-name = "duplicate"; + duplicate-name { }; + phandle-tests { provider0: provider0 { #phandle-cells = <0>; -- cgit v1.2.3-58-ga151 From 367dcb487695e1f219ccac09abf0d7a94bff3355 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 28 Jul 2023 10:50:38 +0200 Subject: of: unittest-data: Fix whitespace - indentation Single space for each indentation level. Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/4df783995a7d34364cb06002bdfeb9eaf2ad4e80.1690533838.git.geert+renesas@glider.be Signed-off-by: Rob Herring --- drivers/of/unittest-data/overlay_bad_add_dup_node.dtso | 6 +++--- drivers/of/unittest-data/overlay_bad_add_dup_prop.dtso | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/unittest-data/overlay_bad_add_dup_node.dtso b/drivers/of/unittest-data/overlay_bad_add_dup_node.dtso index a8d8534f725c..11aa1401244d 100644 --- a/drivers/of/unittest-data/overlay_bad_add_dup_node.dtso +++ b/drivers/of/unittest-data/overlay_bad_add_dup_node.dtso @@ -21,7 +21,7 @@ }; &spin_ctrl_1 { - controller { - power_bus_emergency = < 0x101 0x102 >; - }; + controller { + power_bus_emergency = < 0x101 0x102 >; + }; }; diff --git a/drivers/of/unittest-data/overlay_bad_add_dup_prop.dtso b/drivers/of/unittest-data/overlay_bad_add_dup_prop.dtso index 3f0ee9cbefb8..5af099cc2174 100644 --- a/drivers/of/unittest-data/overlay_bad_add_dup_prop.dtso +++ b/drivers/of/unittest-data/overlay_bad_add_dup_prop.dtso @@ -32,7 +32,7 @@ }; &spin_ctrl_1 { - electric { - rpm_avail = < 100 200 >; - }; + electric { + rpm_avail = < 100 200 >; + }; }; -- cgit v1.2.3-58-ga151 From 58ec916803cd8d3732f21c828f0cc8a103e47cb4 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 28 Jul 2023 10:50:39 +0200 Subject: of: unittest-data: Fix whitespace - angular brackets No space after opening or before closing angular bracket. Signed-off-by: Geert Uytterhoeven Link: https://lore.kernel.org/r/af37e6e73f16d0240a2a1696e21d1d6a3c423ba4.1690533838.git.geert+renesas@glider.be Signed-off-by: Rob Herring --- drivers/of/unittest-data/overlay.dtso | 30 +++++++++---------- .../of/unittest-data/overlay_bad_add_dup_node.dtso | 4 +-- .../of/unittest-data/overlay_bad_add_dup_prop.dtso | 4 +-- drivers/of/unittest-data/overlay_bad_phandle.dtso | 4 +-- drivers/of/unittest-data/overlay_bad_symbol.dtso | 4 +-- drivers/of/unittest-data/overlay_common.dtsi | 34 +++++++++++----------- 6 files changed, 40 insertions(+), 40 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/unittest-data/overlay.dtso b/drivers/of/unittest-data/overlay.dtso index 0c078b08ef08..b3e807b99852 100644 --- a/drivers/of/unittest-data/overlay.dtso +++ b/drivers/of/unittest-data/overlay.dtso @@ -7,8 +7,8 @@ hvac_2: hvac-large-1 { compatible = "ot,hvac-large"; - heat-range = < 40 75 >; - cool-range = < 65 80 >; + heat-range = <40 75>; + cool-range = <65 80>; }; }; @@ -23,11 +23,11 @@ #size-cells = <1>; track@30 { - incline-up = < 48 32 16 >; + incline-up = <48 32 16>; }; track@40 { - incline-up = < 47 31 15 >; + incline-up = <47 31 15>; }; }; @@ -35,22 +35,22 @@ #address-cells = <1>; #size-cells = <1>; compatible = "ot,ferris-wheel"; - reg = < 0x00000200 0x100 >; - hvac-provider = < &hvac_2 >; - hvac-thermostat = < 27 32 > ; - hvac-zones = < 12 5 >; + reg = <0x00000200 0x100>; + hvac-provider = <&hvac_2>; + hvac-thermostat = <27 32> ; + hvac-zones = <12 5>; hvac-zone-names = "operator", "snack-bar"; - spin-controller = < &spin_ctrl_1 3 >; - spin-rph = < 30 >; - gondolas = < 16 >; - gondola-capacity = < 6 >; + spin-controller = <&spin_ctrl_1 3>; + spin-rph = <30>; + gondolas = <16>; + gondola-capacity = <6>; ride_200_left: track@10 { - reg = < 0x00000010 0x10 >; + reg = <0x00000010 0x10>; }; ride_200_right: track@20 { - reg = < 0x00000020 0x10 >; + reg = <0x00000020 0x10>; }; }; }; @@ -58,5 +58,5 @@ &lights_2 { status = "okay"; color = "purple", "white", "red", "green"; - rate = < 3 256 >; + rate = <3 256>; }; diff --git a/drivers/of/unittest-data/overlay_bad_add_dup_node.dtso b/drivers/of/unittest-data/overlay_bad_add_dup_node.dtso index 11aa1401244d..9b53412b2079 100644 --- a/drivers/of/unittest-data/overlay_bad_add_dup_node.dtso +++ b/drivers/of/unittest-data/overlay_bad_add_dup_node.dtso @@ -15,13 +15,13 @@ &electric_1 { motor-1 { controller { - power_bus = < 0x1 0x2 >; + power_bus = <0x1 0x2>; }; }; }; &spin_ctrl_1 { controller { - power_bus_emergency = < 0x101 0x102 >; + power_bus_emergency = <0x101 0x102>; }; }; diff --git a/drivers/of/unittest-data/overlay_bad_add_dup_prop.dtso b/drivers/of/unittest-data/overlay_bad_add_dup_prop.dtso index 5af099cc2174..e03f791655b0 100644 --- a/drivers/of/unittest-data/overlay_bad_add_dup_prop.dtso +++ b/drivers/of/unittest-data/overlay_bad_add_dup_prop.dtso @@ -26,13 +26,13 @@ &electric_1 { motor-1 { electric { - rpm_avail = < 100 >; + rpm_avail = <100>; }; }; }; &spin_ctrl_1 { electric { - rpm_avail = < 100 200 >; + rpm_avail = <100 200>; }; }; diff --git a/drivers/of/unittest-data/overlay_bad_phandle.dtso b/drivers/of/unittest-data/overlay_bad_phandle.dtso index ab2c7df10196..a61ffc0738e3 100644 --- a/drivers/of/unittest-data/overlay_bad_phandle.dtso +++ b/drivers/of/unittest-data/overlay_bad_phandle.dtso @@ -7,7 +7,7 @@ // is applied. There is already a phandle value // in the base tree for motor-1. spin_ctrl_1_conflict: motor-1 { - accelerate = < 3 >; - decelerate = < 5 >; + accelerate = <3>; + decelerate = <5>; }; }; diff --git a/drivers/of/unittest-data/overlay_bad_symbol.dtso b/drivers/of/unittest-data/overlay_bad_symbol.dtso index 5d4e34baf1d8..07f730384cdd 100644 --- a/drivers/of/unittest-data/overlay_bad_symbol.dtso +++ b/drivers/of/unittest-data/overlay_bad_symbol.dtso @@ -8,8 +8,8 @@ // in the base tree hvac_1: hvac-medium-2 { compatible = "ot,hvac-medium"; - heat-range = < 50 75 >; - cool-range = < 60 80 >; + heat-range = <50 75>; + cool-range = <60 80>; }; }; diff --git a/drivers/of/unittest-data/overlay_common.dtsi b/drivers/of/unittest-data/overlay_common.dtsi index 491b89c43cf3..a9d7cdbd5ddc 100644 --- a/drivers/of/unittest-data/overlay_common.dtsi +++ b/drivers/of/unittest-data/overlay_common.dtsi @@ -16,19 +16,19 @@ electric_1: substation@100 { compatible = "ot,big-volts-control"; - reg = < 0x00000100 0x100 >; + reg = <0x00000100 0x100>; status = "disabled"; hvac_1: hvac-medium-1 { compatible = "ot,hvac-medium"; - heat-range = < 50 75 >; - cool-range = < 60 80 >; + heat-range = <50 75>; + cool-range = <60 80>; }; spin_ctrl_1: motor-1 { compatible = "ot,ferris-wheel-motor"; spin = "clockwise"; - rpm_avail = < 50 >; + rpm_avail = <50>; }; spin_ctrl_2: motor-8 { @@ -41,27 +41,27 @@ #size-cells = <1>; compatible = "ot,rides"; status = "disabled"; - orientation = < 127 >; + orientation = <127>; ride@100 { #address-cells = <1>; #size-cells = <1>; compatible = "ot,roller-coaster"; - reg = < 0x00000100 0x100 >; - hvac-provider = < &hvac_1 >; - hvac-thermostat = < 29 > ; - hvac-zones = < 14 >; + reg = <0x00000100 0x100>; + hvac-provider = <&hvac_1>; + hvac-thermostat = <29> ; + hvac-zones = <14>; hvac-zone-names = "operator"; - spin-controller = < &spin_ctrl_2 5 &spin_ctrl_2 7 >; + spin-controller = <&spin_ctrl_2 5 &spin_ctrl_2 7>; spin-controller-names = "track_1", "track_2"; - queues = < 2 >; + queues = <2>; track@30 { - reg = < 0x00000030 0x10 >; + reg = <0x00000030 0x10>; }; track@40 { - reg = < 0x00000040 0x10 >; + reg = <0x00000040 0x10>; }; }; @@ -69,19 +69,19 @@ lights_1: lights@30000 { compatible = "ot,work-lights"; - reg = < 0x00030000 0x1000 >; + reg = <0x00030000 0x1000>; status = "disabled"; }; lights_2: lights@40000 { compatible = "ot,show-lights"; - reg = < 0x00040000 0x1000 >; + reg = <0x00040000 0x1000>; status = "disabled"; - rate = < 13 138 >; + rate = <13 138>; }; retail_1: vending@50000 { - reg = < 0x00050000 0x1000 >; + reg = <0x00050000 0x1000>; compatible = "ot,tickets"; status = "disabled"; }; -- cgit v1.2.3-58-ga151 From 5a7319b967b66969e3fff7b91bdfbcd9acd969ac Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 24 Aug 2023 17:17:34 -0500 Subject: of: unittest: Fix of_unittest_pci_node() kconfig dependencies of_unittest_pci_node test depends on both CONFIG_PCI_DYNAMIC_OF_NODES and CONFIG_OF_OVERLAY. Move the test into the existing CONFIG_OF_OVERLAY ifdef and rework the CONFIG_PCI_DYNAMIC_OF_NODES dependency to use IS_ENABLED() instead. This reduces the combinations to build. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202308241954.oRNfVqmB-lkp@intel.com/ Fixes: 26409dd04589 ("of: unittest: Add pci_dt_testdrv pci driver") Cc: Lizhi Hou Acked-by: Randy Dunlap Tested-by: Randy Dunlap Link: https://lore.kernel.org/r/20230824221743.1581707-1-robh@kernel.org Signed-off-by: Rob Herring --- drivers/of/unittest.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'drivers/of') diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c index 9c0f352cb241..ad2b7879cc67 100644 --- a/drivers/of/unittest.c +++ b/drivers/of/unittest.c @@ -3799,14 +3799,6 @@ err_unlock: mutex_unlock(&of_mutex); } -#else - -static inline __init void of_unittest_overlay_high_level(void) {} - -#endif - -#ifdef CONFIG_PCI_DYNAMIC_OF_NODES - static int of_unittest_pci_dev_num; static int of_unittest_pci_child_num; @@ -3954,6 +3946,9 @@ static void __init of_unittest_pci_node(void) struct pci_dev *pdev = NULL; int rc; + if (!IS_ENABLED(CONFIG_PCI_DYNAMIC_OF_NODES)) + return; + rc = pci_register_driver(&testdrv_driver); unittest(!rc, "Failed to register pci test driver; rc = %d\n", rc); if (rc) @@ -3987,7 +3982,10 @@ static void __init of_unittest_pci_node(void) pci_dev_put(pdev); } #else -static void __init of_unittest_pci_node(void) { } + +static inline __init void of_unittest_overlay_high_level(void) {} +static inline __init void of_unittest_pci_node(void) { } + #endif static int __init of_unittest(void) -- cgit v1.2.3-58-ga151