diff options
| author | Tom Rini <[email protected]> | 2024-12-06 13:00:52 -0600 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2024-12-06 13:00:52 -0600 |
| commit | a0c8e3cfbacfadee81bcbbb9a8b8207941affa3a (patch) | |
| tree | 75f55fe4bf7bb5cd97170d9a603bdd93c0de6af2 /drivers/core | |
| parent | fe76d868f72e483f71a59639c8aa8f658a313b5d (diff) | |
| parent | 68312417b87cd889e6405aadc987172870fb2716 (diff) | |
Merge patch series "led: update LED boot/activity to new property implementation"
Christian Marangi <[email protected]> says:
This series is split in 2 part.
While adapting the LED boot and activity code to the new property
accepted by Rob in dt-schema repository, a big BUG was discovered.
The reason wasn't clear at start and took me some days to figure it
out.
This was triggered by adding a new phandle in the test.dts to
introduce test for the new OPs.
This single addition caused the sandbox CI test to fail in the
dm_test_ofnode_phandle_ot test.
This doesn't make sense as reverting the change made the CI test
to correctly finish. Also moving the uboot node down
after the first phandle (in test.dts the gpio one) also made
the CI test to correctly finish.
A little bit of searching and debugging made me realize the
parse phandle OPs didn't support other.dts at all and they
were still referencing phandle index from test.dts.
(more info in the related commit)
In short the test was broken all along and was working by
pure luck. The first 4 patch address and fix the problem for good.
The other 4 patch expand and address the property change for
LED boot/activity.
Posting in a single series as changes are trivial and just
to speedup review process. (and also because the second
part depends on the first)
All CI tested with azure pipeline.
Link: https://lore.kernel.org/r/[email protected]
Diffstat (limited to 'drivers/core')
| -rw-r--r-- | drivers/core/of_access.c | 61 | ||||
| -rw-r--r-- | drivers/core/ofnode.c | 124 |
2 files changed, 165 insertions, 20 deletions
diff --git a/drivers/core/of_access.c b/drivers/core/of_access.c index 77acd766262..b11e36202c1 100644 --- a/drivers/core/of_access.c +++ b/drivers/core/of_access.c @@ -666,11 +666,12 @@ int of_property_read_string_helper(const struct device_node *np, return i <= 0 ? -ENODATA : i; } -static int __of_parse_phandle_with_args(const struct device_node *np, - const char *list_name, - const char *cells_name, - int cell_count, int index, - struct of_phandle_args *out_args) +static int __of_root_parse_phandle_with_args(struct device_node *root, + const struct device_node *np, + const char *list_name, + const char *cells_name, + int cell_count, int index, + struct of_phandle_args *out_args) { const __be32 *list, *list_end; int rc = 0, cur_index = 0; @@ -706,7 +707,7 @@ static int __of_parse_phandle_with_args(const struct device_node *np, * below. */ if (cells_name || cur_index == index) { - node = of_find_node_by_phandle(NULL, phandle); + node = of_find_node_by_phandle(root, phandle); if (!node) { dm_warn("%s: could not find phandle\n", np->full_name); @@ -783,39 +784,65 @@ static int __of_parse_phandle_with_args(const struct device_node *np, return rc; } -struct device_node *of_parse_phandle(const struct device_node *np, - const char *phandle_name, int index) +struct device_node *of_root_parse_phandle(struct device_node *root, + const struct device_node *np, + const char *phandle_name, int index) { struct of_phandle_args args; if (index < 0) return NULL; - if (__of_parse_phandle_with_args(np, phandle_name, NULL, 0, index, - &args)) + if (__of_root_parse_phandle_with_args(root, np, phandle_name, NULL, 0, + index, &args)) return NULL; return args.np; } +int of_root_parse_phandle_with_args(struct device_node *root, + const struct device_node *np, + const char *list_name, const char *cells_name, + int cell_count, int index, + struct of_phandle_args *out_args) +{ + if (index < 0) + return -EINVAL; + + return __of_root_parse_phandle_with_args(root, np, list_name, cells_name, + cell_count, index, out_args); +} + +int of_root_count_phandle_with_args(struct device_node *root, + const struct device_node *np, + const char *list_name, const char *cells_name, + int cell_count) +{ + return __of_root_parse_phandle_with_args(root, np, list_name, cells_name, + cell_count, -1, NULL); +} + +struct device_node *of_parse_phandle(const struct device_node *np, + const char *phandle_name, int index) +{ + return of_root_parse_phandle(NULL, np, phandle_name, index); +} + int of_parse_phandle_with_args(const struct device_node *np, const char *list_name, const char *cells_name, int cell_count, int index, struct of_phandle_args *out_args) { - if (index < 0) - return -EINVAL; - - return __of_parse_phandle_with_args(np, list_name, cells_name, - cell_count, index, out_args); + return of_root_parse_phandle_with_args(NULL, np, list_name, cells_name, + cell_count, index, out_args); } int of_count_phandle_with_args(const struct device_node *np, const char *list_name, const char *cells_name, int cell_count) { - return __of_parse_phandle_with_args(np, list_name, cells_name, - cell_count, -1, NULL); + return of_root_count_phandle_with_args(NULL, np, list_name, cells_name, + cell_count); } static void of_alias_add(struct alias_prop *ap, struct device_node *np, diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index 950895e72a9..c8161827d1c 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -879,11 +879,69 @@ int ofnode_read_string_list(ofnode node, const char *property, return count; } -static void ofnode_from_fdtdec_phandle_args(struct fdtdec_phandle_args *in, +ofnode ofnode_parse_phandle(ofnode node, const char *phandle_name, + int index) +{ + ofnode phandle; + + if (ofnode_is_np(node)) { + struct device_node *np; + + np = of_parse_phandle(ofnode_to_np(node), phandle_name, + index); + if (!np) + return ofnode_null(); + + phandle = np_to_ofnode(np); + } else { + struct fdtdec_phandle_args args; + + if (fdtdec_parse_phandle_with_args(ofnode_to_fdt(node), + ofnode_to_offset(node), + phandle_name, NULL, + 0, index, &args)) + return ofnode_null(); + + phandle = offset_to_ofnode(args.node); + } + + return phandle; +} + +ofnode oftree_parse_phandle(oftree tree, ofnode node, const char *phandle_name, + int index) +{ + ofnode phandle; + + if (ofnode_is_np(node)) { + struct device_node *np; + + np = of_root_parse_phandle(tree.np, ofnode_to_np(node), + phandle_name, index); + if (!np) + return ofnode_null(); + + phandle = np_to_ofnode(np); + } else { + struct fdtdec_phandle_args args; + + if (fdtdec_parse_phandle_with_args(tree.fdt, + ofnode_to_offset(node), + phandle_name, NULL, + 0, index, &args)) + return ofnode_null(); + + phandle = noffset_to_ofnode(node, args.node); + } + + return phandle; +} + +static void ofnode_from_fdtdec_phandle_args(ofnode node, struct fdtdec_phandle_args *in, struct ofnode_phandle_args *out) { assert(OF_MAX_PHANDLE_ARGS == MAX_PHANDLE_ARGS); - out->node = offset_to_ofnode(in->node); + out->node = noffset_to_ofnode(node, in->node); out->args_count = in->args_count; memcpy(out->args, in->args, sizeof(out->args)); } @@ -923,7 +981,40 @@ int ofnode_parse_phandle_with_args(ofnode node, const char *list_name, cell_count, index, &args); if (ret) return ret; - ofnode_from_fdtdec_phandle_args(&args, out_args); + ofnode_from_fdtdec_phandle_args(node, &args, out_args); + } + + return 0; +} + +int oftree_parse_phandle_with_args(oftree tree, ofnode node, const char *list_name, + const char *cells_name, int cell_count, + int index, + struct ofnode_phandle_args *out_args) +{ + if (ofnode_is_np(node)) { + struct of_phandle_args args; + int ret; + + ret = of_root_parse_phandle_with_args(tree.np, + ofnode_to_np(node), + list_name, cells_name, + cell_count, index, + &args); + if (ret) + return ret; + ofnode_from_of_phandle_args(&args, out_args); + } else { + struct fdtdec_phandle_args args; + int ret; + + ret = fdtdec_parse_phandle_with_args(tree.fdt, + ofnode_to_offset(node), + list_name, cells_name, + cell_count, index, &args); + if (ret) + return ret; + ofnode_from_fdtdec_phandle_args(node, &args, out_args); } return 0; @@ -941,6 +1032,18 @@ int ofnode_count_phandle_with_args(ofnode node, const char *list_name, cell_count, -1, NULL); } +int oftree_count_phandle_with_args(oftree tree, ofnode node, const char *list_name, + const char *cells_name, int cell_count) +{ + if (ofnode_is_np(node)) + return of_root_count_phandle_with_args(tree.np, ofnode_to_np(node), + list_name, cells_name, cell_count); + else + return fdtdec_parse_phandle_with_args(tree.fdt, + ofnode_to_offset(node), list_name, cells_name, + cell_count, -1, NULL); +} + ofnode ofnode_path(const char *path) { if (of_live_active()) @@ -1768,6 +1871,21 @@ const char *ofnode_options_read_str(const char *prop_name) return ofnode_read_string(uboot, prop_name); } +int ofnode_options_get_by_phandle(const char *prop_name, ofnode *nodep) +{ + ofnode uboot; + + uboot = ofnode_path("/options/u-boot"); + if (!ofnode_valid(uboot)) + return -EINVAL; + + *nodep = ofnode_parse_phandle(uboot, prop_name, 0); + if (!ofnode_valid(*nodep)) + return -EINVAL; + + return 0; +} + int ofnode_read_bootscript_address(u64 *bootscr_address, u64 *bootscr_offset) { int ret; |
