xref: /linux-6.15/include/linux/of_graph.h (revision 58fe47d6)
1af6074fcSRob Herring /* SPDX-License-Identifier: GPL-2.0 */
2fd9fdb78SPhilipp Zabel /*
3fd9fdb78SPhilipp Zabel  * OF graph binding parsing helpers
4fd9fdb78SPhilipp Zabel  *
5fd9fdb78SPhilipp Zabel  * Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd.
6fd9fdb78SPhilipp Zabel  * Author: Sylwester Nawrocki <[email protected]>
7fd9fdb78SPhilipp Zabel  *
8fd9fdb78SPhilipp Zabel  * Copyright (C) 2012 Renesas Electronics Corp.
9fd9fdb78SPhilipp Zabel  * Author: Guennadi Liakhovetski <[email protected]>
10fd9fdb78SPhilipp Zabel  */
11fd9fdb78SPhilipp Zabel #ifndef __LINUX_OF_GRAPH_H
12fd9fdb78SPhilipp Zabel #define __LINUX_OF_GRAPH_H
13fd9fdb78SPhilipp Zabel 
1402ac5f9dSKuninori Morimoto #include <linux/cleanup.h>
1501218bf1SMark Brown #include <linux/types.h>
16011d6f5cSArnd Bergmann #include <linux/errno.h>
1701218bf1SMark Brown 
18f2a575f6SPhilipp Zabel /**
19f2a575f6SPhilipp Zabel  * struct of_endpoint - the OF graph endpoint data structure
20f2a575f6SPhilipp Zabel  * @port: identifier (value of reg property) of a port this endpoint belongs to
21f2a575f6SPhilipp Zabel  * @id: identifier (value of reg property) of this endpoint
22f2a575f6SPhilipp Zabel  * @local_node: pointer to device_node of this endpoint
23f2a575f6SPhilipp Zabel  */
24f2a575f6SPhilipp Zabel struct of_endpoint {
25f2a575f6SPhilipp Zabel 	unsigned int port;
26f2a575f6SPhilipp Zabel 	unsigned int id;
27f2a575f6SPhilipp Zabel 	const struct device_node *local_node;
28f2a575f6SPhilipp Zabel };
29f2a575f6SPhilipp Zabel 
30ee890596SPhilipp Zabel /**
31ee890596SPhilipp Zabel  * for_each_endpoint_of_node - iterate over every endpoint in a device node
32ee890596SPhilipp Zabel  * @parent: parent device node containing ports and endpoints
33ee890596SPhilipp Zabel  * @child: loop variable pointing to the current endpoint node
34ee890596SPhilipp Zabel  *
35ee890596SPhilipp Zabel  * When breaking out of the loop, of_node_put(child) has to be called manually.
36ee890596SPhilipp Zabel  */
37ee890596SPhilipp Zabel #define for_each_endpoint_of_node(parent, child) \
38ee890596SPhilipp Zabel 	for (child = of_graph_get_next_endpoint(parent, NULL); child != NULL; \
39ee890596SPhilipp Zabel 	     child = of_graph_get_next_endpoint(parent, child))
40ee890596SPhilipp Zabel 
4102ac5f9dSKuninori Morimoto /**
4202ac5f9dSKuninori Morimoto  * for_each_of_graph_port - iterate over every port in a device or ports node
4302ac5f9dSKuninori Morimoto  * @parent: parent device or ports node containing port
4402ac5f9dSKuninori Morimoto  * @child: loop variable pointing to the current port node
4502ac5f9dSKuninori Morimoto  *
4602ac5f9dSKuninori Morimoto  * When breaking out of the loop, and continue to use the @child, you need to
4702ac5f9dSKuninori Morimoto  * use return_ptr(@child) or no_free_ptr(@child) not to call __free() for it.
4802ac5f9dSKuninori Morimoto  */
4902ac5f9dSKuninori Morimoto #define for_each_of_graph_port(parent, child)			\
5002ac5f9dSKuninori Morimoto 	for (struct device_node *child __free(device_node) = of_graph_get_next_port(parent, NULL);\
5102ac5f9dSKuninori Morimoto 	     child != NULL; child = of_graph_get_next_port(parent, child))
5202ac5f9dSKuninori Morimoto 
53*58fe47d6SKuninori Morimoto /**
54*58fe47d6SKuninori Morimoto  * for_each_of_graph_port_endpoint - iterate over every endpoint in a port node
55*58fe47d6SKuninori Morimoto  * @parent: parent port node
56*58fe47d6SKuninori Morimoto  * @child: loop variable pointing to the current endpoint node
57*58fe47d6SKuninori Morimoto  *
58*58fe47d6SKuninori Morimoto  * When breaking out of the loop, and continue to use the @child, you need to
59*58fe47d6SKuninori Morimoto  * use return_ptr(@child) or no_free_ptr(@child) not to call __free() for it.
60*58fe47d6SKuninori Morimoto  */
61*58fe47d6SKuninori Morimoto #define for_each_of_graph_port_endpoint(parent, child)			\
62*58fe47d6SKuninori Morimoto 	for (struct device_node *child __free(device_node) = of_graph_get_next_port_endpoint(parent, NULL);\
63*58fe47d6SKuninori Morimoto 	     child != NULL; child = of_graph_get_next_port_endpoint(parent, child))
64*58fe47d6SKuninori Morimoto 
65fd9fdb78SPhilipp Zabel #ifdef CONFIG_OF
664ec0a44bSDmitry Osipenko bool of_graph_is_present(const struct device_node *node);
67f2a575f6SPhilipp Zabel int of_graph_parse_endpoint(const struct device_node *node,
68f2a575f6SPhilipp Zabel 				struct of_endpoint *endpoint);
6957484905SKuninori Morimoto unsigned int of_graph_get_endpoint_count(const struct device_node *np);
7002ac5f9dSKuninori Morimoto unsigned int of_graph_get_port_count(struct device_node *np);
71bfe446e3SPhilipp Zabel struct device_node *of_graph_get_port_by_id(struct device_node *node, u32 id);
72fd9fdb78SPhilipp Zabel struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
73fd9fdb78SPhilipp Zabel 					struct device_node *previous);
7402ac5f9dSKuninori Morimoto struct device_node *of_graph_get_next_port(const struct device_node *parent,
7502ac5f9dSKuninori Morimoto 					   struct device_node *port);
76*58fe47d6SKuninori Morimoto struct device_node *of_graph_get_next_port_endpoint(const struct device_node *port,
77*58fe47d6SKuninori Morimoto 						    struct device_node *prev);
788ccd0d0cSHyungwon Hwang struct device_node *of_graph_get_endpoint_by_regs(
798ccd0d0cSHyungwon Hwang 		const struct device_node *parent, int port_reg, int reg);
804c9c3d59SKuninori Morimoto struct device_node *of_graph_get_remote_endpoint(
814c9c3d59SKuninori Morimoto 					const struct device_node *node);
820ef472a9SKuninori Morimoto struct device_node *of_graph_get_port_parent(struct device_node *node);
83fd9fdb78SPhilipp Zabel struct device_node *of_graph_get_remote_port_parent(
84fd9fdb78SPhilipp Zabel 					const struct device_node *node);
85fd9fdb78SPhilipp Zabel struct device_node *of_graph_get_remote_port(const struct device_node *node);
86b85ad494SRob Herring struct device_node *of_graph_get_remote_node(const struct device_node *node,
87b85ad494SRob Herring 					     u32 port, u32 endpoint);
88fd9fdb78SPhilipp Zabel #else
89fd9fdb78SPhilipp Zabel 
of_graph_is_present(const struct device_node * node)904ec0a44bSDmitry Osipenko static inline bool of_graph_is_present(const struct device_node *node)
914ec0a44bSDmitry Osipenko {
924ec0a44bSDmitry Osipenko 	return false;
934ec0a44bSDmitry Osipenko }
944ec0a44bSDmitry Osipenko 
of_graph_parse_endpoint(const struct device_node * node,struct of_endpoint * endpoint)95f2a575f6SPhilipp Zabel static inline int of_graph_parse_endpoint(const struct device_node *node,
9600fd9619SPhilipp Zabel 					struct of_endpoint *endpoint)
97f2a575f6SPhilipp Zabel {
98f2a575f6SPhilipp Zabel 	return -ENOSYS;
99f2a575f6SPhilipp Zabel }
100f2a575f6SPhilipp Zabel 
of_graph_get_endpoint_count(const struct device_node * np)10157484905SKuninori Morimoto static inline unsigned int of_graph_get_endpoint_count(const struct device_node *np)
102ac1e6958SKuninori Morimoto {
103ac1e6958SKuninori Morimoto 	return 0;
104ac1e6958SKuninori Morimoto }
105ac1e6958SKuninori Morimoto 
of_graph_get_port_count(struct device_node * np)10602ac5f9dSKuninori Morimoto static inline unsigned int of_graph_get_port_count(struct device_node *np)
10702ac5f9dSKuninori Morimoto {
10802ac5f9dSKuninori Morimoto 	return 0;
10902ac5f9dSKuninori Morimoto }
11002ac5f9dSKuninori Morimoto 
of_graph_get_port_by_id(struct device_node * node,u32 id)111bfe446e3SPhilipp Zabel static inline struct device_node *of_graph_get_port_by_id(
112bfe446e3SPhilipp Zabel 					struct device_node *node, u32 id)
113bfe446e3SPhilipp Zabel {
114bfe446e3SPhilipp Zabel 	return NULL;
115bfe446e3SPhilipp Zabel }
116bfe446e3SPhilipp Zabel 
of_graph_get_next_endpoint(const struct device_node * parent,struct device_node * previous)117fd9fdb78SPhilipp Zabel static inline struct device_node *of_graph_get_next_endpoint(
118fd9fdb78SPhilipp Zabel 					const struct device_node *parent,
119fd9fdb78SPhilipp Zabel 					struct device_node *previous)
120fd9fdb78SPhilipp Zabel {
121fd9fdb78SPhilipp Zabel 	return NULL;
122fd9fdb78SPhilipp Zabel }
123fd9fdb78SPhilipp Zabel 
of_graph_get_next_port(const struct device_node * parent,struct device_node * previous)12402ac5f9dSKuninori Morimoto static inline struct device_node *of_graph_get_next_port(
12502ac5f9dSKuninori Morimoto 					const struct device_node *parent,
12602ac5f9dSKuninori Morimoto 					struct device_node *previous)
12702ac5f9dSKuninori Morimoto {
12802ac5f9dSKuninori Morimoto 	return NULL;
12902ac5f9dSKuninori Morimoto }
13002ac5f9dSKuninori Morimoto 
of_graph_get_next_port_endpoint(const struct device_node * parent,struct device_node * previous)131*58fe47d6SKuninori Morimoto static inline struct device_node *of_graph_get_next_port_endpoint(
132*58fe47d6SKuninori Morimoto 					const struct device_node *parent,
133*58fe47d6SKuninori Morimoto 					struct device_node *previous)
134*58fe47d6SKuninori Morimoto {
135*58fe47d6SKuninori Morimoto 	return NULL;
136*58fe47d6SKuninori Morimoto }
137*58fe47d6SKuninori Morimoto 
of_graph_get_endpoint_by_regs(const struct device_node * parent,int port_reg,int reg)138ce0bdb84SInki Dae static inline struct device_node *of_graph_get_endpoint_by_regs(
1398ccd0d0cSHyungwon Hwang 		const struct device_node *parent, int port_reg, int reg)
1408ccd0d0cSHyungwon Hwang {
1418ccd0d0cSHyungwon Hwang 	return NULL;
1428ccd0d0cSHyungwon Hwang }
1438ccd0d0cSHyungwon Hwang 
of_graph_get_remote_endpoint(const struct device_node * node)1444c9c3d59SKuninori Morimoto static inline struct device_node *of_graph_get_remote_endpoint(
1454c9c3d59SKuninori Morimoto 					const struct device_node *node)
1464c9c3d59SKuninori Morimoto {
1474c9c3d59SKuninori Morimoto 	return NULL;
1484c9c3d59SKuninori Morimoto }
1494c9c3d59SKuninori Morimoto 
of_graph_get_port_parent(struct device_node * node)1500ef472a9SKuninori Morimoto static inline struct device_node *of_graph_get_port_parent(
1510ef472a9SKuninori Morimoto 	struct device_node *node)
1520ef472a9SKuninori Morimoto {
1530ef472a9SKuninori Morimoto 	return NULL;
1540ef472a9SKuninori Morimoto }
1550ef472a9SKuninori Morimoto 
of_graph_get_remote_port_parent(const struct device_node * node)156fd9fdb78SPhilipp Zabel static inline struct device_node *of_graph_get_remote_port_parent(
157fd9fdb78SPhilipp Zabel 					const struct device_node *node)
158fd9fdb78SPhilipp Zabel {
159fd9fdb78SPhilipp Zabel 	return NULL;
160fd9fdb78SPhilipp Zabel }
161fd9fdb78SPhilipp Zabel 
of_graph_get_remote_port(const struct device_node * node)162fd9fdb78SPhilipp Zabel static inline struct device_node *of_graph_get_remote_port(
163fd9fdb78SPhilipp Zabel 					const struct device_node *node)
164fd9fdb78SPhilipp Zabel {
165fd9fdb78SPhilipp Zabel 	return NULL;
166fd9fdb78SPhilipp Zabel }
of_graph_get_remote_node(const struct device_node * node,u32 port,u32 endpoint)167b85ad494SRob Herring static inline struct device_node *of_graph_get_remote_node(
168b85ad494SRob Herring 					const struct device_node *node,
169b85ad494SRob Herring 					u32 port, u32 endpoint)
170b85ad494SRob Herring {
171b85ad494SRob Herring 	return NULL;
172b85ad494SRob Herring }
173fd9fdb78SPhilipp Zabel 
174fd9fdb78SPhilipp Zabel #endif /* CONFIG_OF */
175fd9fdb78SPhilipp Zabel 
176fd9fdb78SPhilipp Zabel #endif /* __LINUX_OF_GRAPH_H */
177