public inbox for linux-pm@vger.kernel.org
 help / color / mirror / Atom feed
From: Kevin Hilman <khilman@baylibre.com>
To: Rob Herring <robh@kernel.org>, Herve Codina <herve.codina@bootlin.com>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>,
	devicetree@vger.kernel.org, Ulf Hansson <ulf.hansson@linaro.org>,
	linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH RFC v2] of: Add of_parse_map_iter() helper for nexus node map iteration
Date: Mon, 26 Jan 2026 12:27:49 -0800	[thread overview]
Message-ID: <7hh5s85dbu.fsf@baylibre.com> (raw)
In-Reply-To: <CAL_JsqLq1V_is4wHedFoiGHcYt293vDJ4SsHaZKxYARupbUXEw@mail.gmail.com>

Rob Herring <robh@kernel.org> writes:

> On Wed, Jan 21, 2026 at 5:55 PM Kevin Hilman (TI) <khilman@baylibre.com> wrote:
>>
>> Add a new helper function of_parse_map_iter() to simplify parsing of
>> nexus node maps as defined in the DT spec, section 2.5.1.
>>
>> This function provides an iterator interface for traversing map entries,
>> handling the complexity of variable-sized entries based on #<stem>-cells
>> properties. Each map entry follows the format:
>>   <child_specifier phandle parent_specifier>
>>
>> The iterator extracts both the child specifier and parent phandle+args
>> for each entry, managing all the details of:
>> - Reading #<stem>-cells from both child and parent nodes
>> - Calculating variable entry sizes
>> - Resolving phandles
>> - Proper node reference management
>>
>> This eliminates the need for subsystems to manually parse map properties,
>> reducing code duplication and potential bugs.
>>
>> This code was developed in collaboration with Claude Code (model:
>> Sonnet 4.5), which needed some guidance to use existing OF helpers,
>> iterators etc.
>>
>> Signed-off-by: Kevin Hilman (TI) <khilman@baylibre.com>
>> ---
>> Changes in v2:
>> - Use helpers of_phandle_iterator_init() and of_phandle_iterator_next()
>> - add missing of_node_put() pointed out in v1
>> - Link to v1: https://patch.msgid.link/20251119-topic-lpm-of-map-iterator-v6-18-v1-1-1f0075d771a3@baylibre.com
>> ---
>>  drivers/of/base.c  | 163 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  include/linux/of.h |  13 +++++++++++++
>>  2 files changed, 176 insertions(+)
>>
>> diff --git a/drivers/of/base.c b/drivers/of/base.c
>> index 0b65039ece53..8392fe54cf60 100644
>> --- a/drivers/of/base.c
>> +++ b/drivers/of/base.c
>> @@ -1641,6 +1641,169 @@ int of_parse_phandle_with_args_map(const struct device_node *np,
>>  }
>>  EXPORT_SYMBOL(of_parse_phandle_with_args_map);
>>
>> +/**
>> + * of_parse_map_iter() - Iterate through entries in a nexus node map
>> + * @np:                        pointer to a device tree node containing the map
>> + * @stem_name:         stem of property names (e.g., "power-domain" for "power-domain-map")
>> + * @index:             pointer to iteration index (set to 0 for first call)
>> + * @child_args:                pointer to structure to fill with child specifier (can be NULL)
>> + * @parent_args:       pointer to structure to fill with parent phandle and specifier
>> + *
>> + * This function iterates through a nexus node map property as defined in DT spec 2.5.1.
>> + * Each map entry has the format: <child_specifier phandle parent_specifier>
>> + *
>> + * On each call, it extracts one map entry and fills child_args (if provided) with the
>> + * child specifier and parent_args with the parent phandle and specifier.
>> + * The index pointer is updated to point to the next entry for the following call.
>> + *
>> + * Example usage::
>> + *
>> + *  int index = 0;
>> + *  struct of_phandle_args child_args, parent_args;
>> + *
>> + *  while (!of_parse_map_iter(np, "power-domain", &index, &child_args, &parent_args)) {
>> + *      // Process child_args and parent_args
>> + *      of_node_put(parent_args.np);
>> + *  }
>> + *
>> + * Caller is responsible for calling of_node_put() on parent_args.np.
>> + *
>> + * Return: 0 on success, -ENOENT when iteration is complete, or negative error code on failure.
>> + */
>> +int of_parse_map_iter(const struct device_node *np,
>> +                      const char *stem_name,
>> +                      int *index,
>> +                      struct of_phandle_args *child_args,
>> +                      struct of_phandle_args *parent_args)
>> +{
>> +       char *cells_name __free(kfree) = kasprintf(GFP_KERNEL, "#%s-cells", stem_name);
>> +       char *map_name __free(kfree) = kasprintf(GFP_KERNEL, "%s-map", stem_name);
>> +       char *mask_name __free(kfree) = kasprintf(GFP_KERNEL, "%s-map-mask", stem_name);
>> +       char *pass_name __free(kfree) = kasprintf(GFP_KERNEL, "%s-map-pass-thru", stem_name);
>
> It's not great that we're doing allocs and frees on each iteration.
>
> Can't we follow the same design Herve did for interrupt-map? You have
> an init function you call once up front and then an iterator define
> (e.g. for_each_of_imap_item()). The complication in this case would be
> if we do the allocs in the init function, then we need a way to free
> them. If they are part of the for loop init, then we could use the
> scoped cleanup.
>
> On thing I noticed is I think of_phandle_iterator and of_imap_parser
> should probably be merged to one struct. They basically hold the same
> information (pointers to property data).
>
> Let me see if I can come up with something next week.

Thank you!

I would greatly appreciate some help getting this going in the right
direction as I'm definitely out of my comfort zone in this drivers/of
code.

Kevin

      reply	other threads:[~2026-01-26 20:27 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-21 23:55 [PATCH RFC v2] of: Add of_parse_map_iter() helper for nexus node map iteration Kevin Hilman (TI)
2026-01-24  0:13 ` Rob Herring
2026-01-26 20:27   ` Kevin Hilman [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7hh5s85dbu.fsf@baylibre.com \
    --to=khilman@baylibre.com \
    --cc=devicetree@vger.kernel.org \
    --cc=herve.codina@bootlin.com \
    --cc=krzk+dt@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=robh@kernel.org \
    --cc=ulf.hansson@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox