[PATCH 1/9] of: property: add of_graph_get_next_port()

Kuninori Morimoto kuninori.morimoto.gx at renesas.com
Fri Aug 9 02:10:03 UTC 2024


Hi Tomi

Thank you for your review


> > +/**
> > + * of_graph_get_next_ports() - get next ports node.
> > + * @parent: pointer to the parent device node
> > + * @ports: current ports node, or NULL to get first
> > + *
> > + * Return: A 'ports' node pointer with refcount incremented. Refcount
> > + * of the passed @prev node is decremented.
> 
> No "prev" argument in the code.
> 
> The of_graph_get_next_endpoint() function uses "previous" as the 
> argument name (well, the function declaration uses "previous", the 
> implementation uses "prev"...), and I would use the same naming here.
> 
> Also of_graph_get_next_endpoint() talks about "previous endpoint node", 
> whereas here it's "current ports node". I'd use the same style here, so 
> "previous ports node".
> 
> The same comments for the of_graph_get_next_port().

OK, thanks. Will fix in v2

> > +struct device_node *of_graph_get_next_ports(struct device_node *parent,
> > +					    struct device_node *ports)
> > +{
> > +	if (!parent)
> > +		return NULL;
> > +
> > +	if (!ports) {
> > +		ports = of_get_child_by_name(parent, "ports");
> > +
> > +		/* use parent as its ports of this device if it not exist */
> 
> I think this needs to be described in the kernel doc. I understand the 
> need for this, but it's somewhat counter-intuitive that this returns the 
> parent node if there are no ports nodes, so it must be highlighted in 
> the documentation.
> 
> I wonder if a bit more complexity here would be good... I think here we 
> could:
> 
> - If there are no 'ports' nodes in the parent, but there is a 'port' 
> node in the parent, return the parent node
> - If there are no 'ports' nor 'port' nodes in the parent, return NULL

Thanks, but unfortunately, get_next_ports() checks only "ports" and
doesn't check whether it has "port" node or not.
So correct comment here is maybe...

	If "parent" doesn't have "ports", it returns "parent" itself as "ports"

I will add it on v2

> > +/**
> > + * of_graph_get_next_port() - get next port node.
> > + * @parent: pointer to the parent device node
> > + * @port: current port node, or NULL to get first
> > + *
> > + * Return: A 'port' node pointer with refcount incremented. Refcount
> > + * of the passed @prev node is decremented.
> > + */
> > +struct device_node *of_graph_get_next_port(struct device_node *parent,
> > +					   struct device_node *port)
> > +{
> > +	if (!parent)
> > +		return NULL;
> > +
> > +	if (!port) {
> > +		struct device_node *ports __free(device_node) =
> > +			of_graph_get_next_ports(parent, NULL);
> > +
> > +		return of_get_child_by_name(ports, "port");
> > +	}
> > +
> > +	do {
> > +		port = of_get_next_child(parent, port);
> > +		if (!port)
> > +			break;
> > +	} while (!of_node_name_eq(port, "port"));
> > +
> > +	return port;
> > +}
> 
> Hmm... So if I call this with of_graph_get_next_port(dev_node, NULL) 
> (dev_node being the device node of the device), it'll give me the first 
> port in the first ports node, or the first port in the dev_node if there 
> are no ports nodes?

Yes

> And if I then continue iterating with of_graph_get_next_port(dev_node, 
> prev_port)... The call will return NULL if the dev_node contains "ports" 
> node (because the dev_node does not contain any "port" nodes)?
>
> So if I understand right, of_graph_get_next_port() must always be called 
> with a parent that contains port nodes. Sometimes that's the device's 
> node (if there's just one port) and sometimes that's ports node. If it's 
> called with a parent that contains ports node, it will not work correctly.
>
> If the above is right, then should this just return 
> "of_get_child_by_name(parent, "port")" if !port, instead of calling 
> of_graph_get_next_ports()?

Hmm ?  Do you mean you want access to ports at 1 memeber port after ports at 0 ?
I have tested below in my test environment

	parent {
(X)		ports at 0 {
(A)			port at 0 { };
(B)			port at 1 { };
		};
(Y)		ports at 1 {
(C)			port at 0 { };
		};
	};

In this case, if you call get_next_port() with parent,
you can get ports at 0 member port.

	/* use "paramet" and use "ports at 0" are same result */

	// use parent
	port = of_graph_get_next_port(parent, NULL); // (A)
	port = of_graph_get_next_port(parent, port); // (B)
	port = of_graph_get_next_port(parent, port); // NULl

	// use ports at 0
	ports = of_graph_get_next_ports(parent, NULL); // (X)
	port  = of_graph_get_next_port(ports, NULL);   // (A)
	port  = of_graph_get_next_port(ports, port);   // (B)
	port  = of_graph_get_next_port(ports, port);   // NULl

If you want to get ports at 1 member port, you need to use ports at 1.

	// use ports at 1
	ports = of_graph_get_next_ports(parent, NULL);  // (X)
	ports = of_graph_get_next_ports(parent, ports); // (Y)
	port  = of_graph_get_next_port(ports, NULL);    // (C)

I have confirmed in my test environment.
But please double check it. Is this clear for you ?

> Or maybe I'm just getting confused here. But in any case, I think it 
> would be very good to describe the behavior on the kernel doc for the 
> different ports/port structure cases (also for 
> of_graph_get_next_ports()), and be clear on what the parameters can be, 
> i.e. what kind of device nodes can be given as parent, and how the 
> function iterates over the ports.

OK, will do in v2

> > + * @np: pointer to the parent device node
> > + *
> > + * Return: count of port of this device node
> > + */
> > +unsigned int of_graph_get_port_count(struct device_node *np)
> > +{
> > +	struct device_node *port = NULL;
> > +	int num = 0;
> > +
> > +	for_each_of_graph_port(np, port)
> > +		num++;
> > +
> > +	return num;
> > +}
> 
> I my analysis above is right, calling of_graph_get_port_count(dev_node) 
> will return 1, if the dev_node contains "ports" node which contains one 
> or more "port" nodes.

In my test, it will be..

	parent {
		ports at 0 {
			port at 0 { };
			port at 1 { };
		};
		ports at 1 {
			port at 0 { };
		};
	};

	of_graph_get_port_count(parent); // 2 = number of ports at 0
	of_graph_get_port_count(ports0); // 2 = number of ports at 0
	of_graph_get_port_count(ports1); // 1 = number of ports at 1


Thank you for your help !!

Best regards
---
Kuninori Morimoto


More information about the dri-devel mailing list