xref: /OK3568_Linux_fs/kernel/include/linux/property.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * property.h - Unified device property interface.
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (C) 2014, Intel Corporation
6*4882a593Smuzhiyun  * Authors: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
7*4882a593Smuzhiyun  *          Mika Westerberg <mika.westerberg@linux.intel.com>
8*4882a593Smuzhiyun  */
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #ifndef _LINUX_PROPERTY_H_
11*4882a593Smuzhiyun #define _LINUX_PROPERTY_H_
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #include <linux/bits.h>
14*4882a593Smuzhiyun #include <linux/fwnode.h>
15*4882a593Smuzhiyun #include <linux/types.h>
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun struct device;
18*4882a593Smuzhiyun 
19*4882a593Smuzhiyun enum dev_prop_type {
20*4882a593Smuzhiyun 	DEV_PROP_U8,
21*4882a593Smuzhiyun 	DEV_PROP_U16,
22*4882a593Smuzhiyun 	DEV_PROP_U32,
23*4882a593Smuzhiyun 	DEV_PROP_U64,
24*4882a593Smuzhiyun 	DEV_PROP_STRING,
25*4882a593Smuzhiyun 	DEV_PROP_REF,
26*4882a593Smuzhiyun };
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun enum dev_dma_attr {
29*4882a593Smuzhiyun 	DEV_DMA_NOT_SUPPORTED,
30*4882a593Smuzhiyun 	DEV_DMA_NON_COHERENT,
31*4882a593Smuzhiyun 	DEV_DMA_COHERENT,
32*4882a593Smuzhiyun };
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun struct fwnode_handle *dev_fwnode(struct device *dev);
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun bool device_property_present(struct device *dev, const char *propname);
37*4882a593Smuzhiyun int device_property_read_u8_array(struct device *dev, const char *propname,
38*4882a593Smuzhiyun 				  u8 *val, size_t nval);
39*4882a593Smuzhiyun int device_property_read_u16_array(struct device *dev, const char *propname,
40*4882a593Smuzhiyun 				   u16 *val, size_t nval);
41*4882a593Smuzhiyun int device_property_read_u32_array(struct device *dev, const char *propname,
42*4882a593Smuzhiyun 				   u32 *val, size_t nval);
43*4882a593Smuzhiyun int device_property_read_u64_array(struct device *dev, const char *propname,
44*4882a593Smuzhiyun 				   u64 *val, size_t nval);
45*4882a593Smuzhiyun int device_property_read_string_array(struct device *dev, const char *propname,
46*4882a593Smuzhiyun 				      const char **val, size_t nval);
47*4882a593Smuzhiyun int device_property_read_string(struct device *dev, const char *propname,
48*4882a593Smuzhiyun 				const char **val);
49*4882a593Smuzhiyun int device_property_match_string(struct device *dev,
50*4882a593Smuzhiyun 				 const char *propname, const char *string);
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun bool fwnode_device_is_available(const struct fwnode_handle *fwnode);
53*4882a593Smuzhiyun bool fwnode_property_present(const struct fwnode_handle *fwnode,
54*4882a593Smuzhiyun 			     const char *propname);
55*4882a593Smuzhiyun int fwnode_property_read_u8_array(const struct fwnode_handle *fwnode,
56*4882a593Smuzhiyun 				  const char *propname, u8 *val,
57*4882a593Smuzhiyun 				  size_t nval);
58*4882a593Smuzhiyun int fwnode_property_read_u16_array(const struct fwnode_handle *fwnode,
59*4882a593Smuzhiyun 				   const char *propname, u16 *val,
60*4882a593Smuzhiyun 				   size_t nval);
61*4882a593Smuzhiyun int fwnode_property_read_u32_array(const struct fwnode_handle *fwnode,
62*4882a593Smuzhiyun 				   const char *propname, u32 *val,
63*4882a593Smuzhiyun 				   size_t nval);
64*4882a593Smuzhiyun int fwnode_property_read_u64_array(const struct fwnode_handle *fwnode,
65*4882a593Smuzhiyun 				   const char *propname, u64 *val,
66*4882a593Smuzhiyun 				   size_t nval);
67*4882a593Smuzhiyun int fwnode_property_read_string_array(const struct fwnode_handle *fwnode,
68*4882a593Smuzhiyun 				      const char *propname, const char **val,
69*4882a593Smuzhiyun 				      size_t nval);
70*4882a593Smuzhiyun int fwnode_property_read_string(const struct fwnode_handle *fwnode,
71*4882a593Smuzhiyun 				const char *propname, const char **val);
72*4882a593Smuzhiyun int fwnode_property_match_string(const struct fwnode_handle *fwnode,
73*4882a593Smuzhiyun 				 const char *propname, const char *string);
74*4882a593Smuzhiyun int fwnode_property_get_reference_args(const struct fwnode_handle *fwnode,
75*4882a593Smuzhiyun 				       const char *prop, const char *nargs_prop,
76*4882a593Smuzhiyun 				       unsigned int nargs, unsigned int index,
77*4882a593Smuzhiyun 				       struct fwnode_reference_args *args);
78*4882a593Smuzhiyun 
79*4882a593Smuzhiyun struct fwnode_handle *fwnode_find_reference(const struct fwnode_handle *fwnode,
80*4882a593Smuzhiyun 					    const char *name,
81*4882a593Smuzhiyun 					    unsigned int index);
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun const char *fwnode_get_name(const struct fwnode_handle *fwnode);
84*4882a593Smuzhiyun const char *fwnode_get_name_prefix(const struct fwnode_handle *fwnode);
85*4882a593Smuzhiyun struct fwnode_handle *fwnode_get_parent(const struct fwnode_handle *fwnode);
86*4882a593Smuzhiyun struct fwnode_handle *fwnode_get_next_parent(
87*4882a593Smuzhiyun 	struct fwnode_handle *fwnode);
88*4882a593Smuzhiyun struct device *fwnode_get_next_parent_dev(struct fwnode_handle *fwnode);
89*4882a593Smuzhiyun unsigned int fwnode_count_parents(const struct fwnode_handle *fwn);
90*4882a593Smuzhiyun struct fwnode_handle *fwnode_get_nth_parent(struct fwnode_handle *fwn,
91*4882a593Smuzhiyun 					    unsigned int depth);
92*4882a593Smuzhiyun bool fwnode_is_ancestor_of(struct fwnode_handle *test_ancestor,
93*4882a593Smuzhiyun 				  struct fwnode_handle *test_child);
94*4882a593Smuzhiyun struct fwnode_handle *fwnode_get_next_child_node(
95*4882a593Smuzhiyun 	const struct fwnode_handle *fwnode, struct fwnode_handle *child);
96*4882a593Smuzhiyun struct fwnode_handle *fwnode_get_next_available_child_node(
97*4882a593Smuzhiyun 	const struct fwnode_handle *fwnode, struct fwnode_handle *child);
98*4882a593Smuzhiyun 
99*4882a593Smuzhiyun #define fwnode_for_each_child_node(fwnode, child)			\
100*4882a593Smuzhiyun 	for (child = fwnode_get_next_child_node(fwnode, NULL); child;	\
101*4882a593Smuzhiyun 	     child = fwnode_get_next_child_node(fwnode, child))
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun #define fwnode_for_each_available_child_node(fwnode, child)		       \
104*4882a593Smuzhiyun 	for (child = fwnode_get_next_available_child_node(fwnode, NULL); child;\
105*4882a593Smuzhiyun 	     child = fwnode_get_next_available_child_node(fwnode, child))
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun struct fwnode_handle *device_get_next_child_node(
108*4882a593Smuzhiyun 	struct device *dev, struct fwnode_handle *child);
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun #define device_for_each_child_node(dev, child)				\
111*4882a593Smuzhiyun 	for (child = device_get_next_child_node(dev, NULL); child;	\
112*4882a593Smuzhiyun 	     child = device_get_next_child_node(dev, child))
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun struct fwnode_handle *fwnode_get_named_child_node(
115*4882a593Smuzhiyun 	const struct fwnode_handle *fwnode, const char *childname);
116*4882a593Smuzhiyun struct fwnode_handle *device_get_named_child_node(struct device *dev,
117*4882a593Smuzhiyun 						  const char *childname);
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun struct fwnode_handle *fwnode_handle_get(struct fwnode_handle *fwnode);
120*4882a593Smuzhiyun void fwnode_handle_put(struct fwnode_handle *fwnode);
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun int fwnode_irq_get(struct fwnode_handle *fwnode, unsigned int index);
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun unsigned int device_get_child_node_count(struct device *dev);
125*4882a593Smuzhiyun 
device_property_read_bool(struct device * dev,const char * propname)126*4882a593Smuzhiyun static inline bool device_property_read_bool(struct device *dev,
127*4882a593Smuzhiyun 					     const char *propname)
128*4882a593Smuzhiyun {
129*4882a593Smuzhiyun 	return device_property_present(dev, propname);
130*4882a593Smuzhiyun }
131*4882a593Smuzhiyun 
device_property_read_u8(struct device * dev,const char * propname,u8 * val)132*4882a593Smuzhiyun static inline int device_property_read_u8(struct device *dev,
133*4882a593Smuzhiyun 					  const char *propname, u8 *val)
134*4882a593Smuzhiyun {
135*4882a593Smuzhiyun 	return device_property_read_u8_array(dev, propname, val, 1);
136*4882a593Smuzhiyun }
137*4882a593Smuzhiyun 
device_property_read_u16(struct device * dev,const char * propname,u16 * val)138*4882a593Smuzhiyun static inline int device_property_read_u16(struct device *dev,
139*4882a593Smuzhiyun 					   const char *propname, u16 *val)
140*4882a593Smuzhiyun {
141*4882a593Smuzhiyun 	return device_property_read_u16_array(dev, propname, val, 1);
142*4882a593Smuzhiyun }
143*4882a593Smuzhiyun 
device_property_read_u32(struct device * dev,const char * propname,u32 * val)144*4882a593Smuzhiyun static inline int device_property_read_u32(struct device *dev,
145*4882a593Smuzhiyun 					   const char *propname, u32 *val)
146*4882a593Smuzhiyun {
147*4882a593Smuzhiyun 	return device_property_read_u32_array(dev, propname, val, 1);
148*4882a593Smuzhiyun }
149*4882a593Smuzhiyun 
device_property_read_u64(struct device * dev,const char * propname,u64 * val)150*4882a593Smuzhiyun static inline int device_property_read_u64(struct device *dev,
151*4882a593Smuzhiyun 					   const char *propname, u64 *val)
152*4882a593Smuzhiyun {
153*4882a593Smuzhiyun 	return device_property_read_u64_array(dev, propname, val, 1);
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun 
device_property_count_u8(struct device * dev,const char * propname)156*4882a593Smuzhiyun static inline int device_property_count_u8(struct device *dev, const char *propname)
157*4882a593Smuzhiyun {
158*4882a593Smuzhiyun 	return device_property_read_u8_array(dev, propname, NULL, 0);
159*4882a593Smuzhiyun }
160*4882a593Smuzhiyun 
device_property_count_u16(struct device * dev,const char * propname)161*4882a593Smuzhiyun static inline int device_property_count_u16(struct device *dev, const char *propname)
162*4882a593Smuzhiyun {
163*4882a593Smuzhiyun 	return device_property_read_u16_array(dev, propname, NULL, 0);
164*4882a593Smuzhiyun }
165*4882a593Smuzhiyun 
device_property_count_u32(struct device * dev,const char * propname)166*4882a593Smuzhiyun static inline int device_property_count_u32(struct device *dev, const char *propname)
167*4882a593Smuzhiyun {
168*4882a593Smuzhiyun 	return device_property_read_u32_array(dev, propname, NULL, 0);
169*4882a593Smuzhiyun }
170*4882a593Smuzhiyun 
device_property_count_u64(struct device * dev,const char * propname)171*4882a593Smuzhiyun static inline int device_property_count_u64(struct device *dev, const char *propname)
172*4882a593Smuzhiyun {
173*4882a593Smuzhiyun 	return device_property_read_u64_array(dev, propname, NULL, 0);
174*4882a593Smuzhiyun }
175*4882a593Smuzhiyun 
device_property_string_array_count(struct device * dev,const char * propname)176*4882a593Smuzhiyun static inline int device_property_string_array_count(struct device *dev,
177*4882a593Smuzhiyun 						     const char *propname)
178*4882a593Smuzhiyun {
179*4882a593Smuzhiyun 	return device_property_read_string_array(dev, propname, NULL, 0);
180*4882a593Smuzhiyun }
181*4882a593Smuzhiyun 
fwnode_property_read_bool(const struct fwnode_handle * fwnode,const char * propname)182*4882a593Smuzhiyun static inline bool fwnode_property_read_bool(const struct fwnode_handle *fwnode,
183*4882a593Smuzhiyun 					     const char *propname)
184*4882a593Smuzhiyun {
185*4882a593Smuzhiyun 	return fwnode_property_present(fwnode, propname);
186*4882a593Smuzhiyun }
187*4882a593Smuzhiyun 
fwnode_property_read_u8(const struct fwnode_handle * fwnode,const char * propname,u8 * val)188*4882a593Smuzhiyun static inline int fwnode_property_read_u8(const struct fwnode_handle *fwnode,
189*4882a593Smuzhiyun 					  const char *propname, u8 *val)
190*4882a593Smuzhiyun {
191*4882a593Smuzhiyun 	return fwnode_property_read_u8_array(fwnode, propname, val, 1);
192*4882a593Smuzhiyun }
193*4882a593Smuzhiyun 
fwnode_property_read_u16(const struct fwnode_handle * fwnode,const char * propname,u16 * val)194*4882a593Smuzhiyun static inline int fwnode_property_read_u16(const struct fwnode_handle *fwnode,
195*4882a593Smuzhiyun 					   const char *propname, u16 *val)
196*4882a593Smuzhiyun {
197*4882a593Smuzhiyun 	return fwnode_property_read_u16_array(fwnode, propname, val, 1);
198*4882a593Smuzhiyun }
199*4882a593Smuzhiyun 
fwnode_property_read_u32(const struct fwnode_handle * fwnode,const char * propname,u32 * val)200*4882a593Smuzhiyun static inline int fwnode_property_read_u32(const struct fwnode_handle *fwnode,
201*4882a593Smuzhiyun 					   const char *propname, u32 *val)
202*4882a593Smuzhiyun {
203*4882a593Smuzhiyun 	return fwnode_property_read_u32_array(fwnode, propname, val, 1);
204*4882a593Smuzhiyun }
205*4882a593Smuzhiyun 
fwnode_property_read_u64(const struct fwnode_handle * fwnode,const char * propname,u64 * val)206*4882a593Smuzhiyun static inline int fwnode_property_read_u64(const struct fwnode_handle *fwnode,
207*4882a593Smuzhiyun 					   const char *propname, u64 *val)
208*4882a593Smuzhiyun {
209*4882a593Smuzhiyun 	return fwnode_property_read_u64_array(fwnode, propname, val, 1);
210*4882a593Smuzhiyun }
211*4882a593Smuzhiyun 
fwnode_property_count_u8(const struct fwnode_handle * fwnode,const char * propname)212*4882a593Smuzhiyun static inline int fwnode_property_count_u8(const struct fwnode_handle *fwnode,
213*4882a593Smuzhiyun 					   const char *propname)
214*4882a593Smuzhiyun {
215*4882a593Smuzhiyun 	return fwnode_property_read_u8_array(fwnode, propname, NULL, 0);
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun 
fwnode_property_count_u16(const struct fwnode_handle * fwnode,const char * propname)218*4882a593Smuzhiyun static inline int fwnode_property_count_u16(const struct fwnode_handle *fwnode,
219*4882a593Smuzhiyun 					    const char *propname)
220*4882a593Smuzhiyun {
221*4882a593Smuzhiyun 	return fwnode_property_read_u16_array(fwnode, propname, NULL, 0);
222*4882a593Smuzhiyun }
223*4882a593Smuzhiyun 
fwnode_property_count_u32(const struct fwnode_handle * fwnode,const char * propname)224*4882a593Smuzhiyun static inline int fwnode_property_count_u32(const struct fwnode_handle *fwnode,
225*4882a593Smuzhiyun 					    const char *propname)
226*4882a593Smuzhiyun {
227*4882a593Smuzhiyun 	return fwnode_property_read_u32_array(fwnode, propname, NULL, 0);
228*4882a593Smuzhiyun }
229*4882a593Smuzhiyun 
fwnode_property_count_u64(const struct fwnode_handle * fwnode,const char * propname)230*4882a593Smuzhiyun static inline int fwnode_property_count_u64(const struct fwnode_handle *fwnode,
231*4882a593Smuzhiyun 					    const char *propname)
232*4882a593Smuzhiyun {
233*4882a593Smuzhiyun 	return fwnode_property_read_u64_array(fwnode, propname, NULL, 0);
234*4882a593Smuzhiyun }
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun static inline int
fwnode_property_string_array_count(const struct fwnode_handle * fwnode,const char * propname)237*4882a593Smuzhiyun fwnode_property_string_array_count(const struct fwnode_handle *fwnode,
238*4882a593Smuzhiyun 				   const char *propname)
239*4882a593Smuzhiyun {
240*4882a593Smuzhiyun 	return fwnode_property_read_string_array(fwnode, propname, NULL, 0);
241*4882a593Smuzhiyun }
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun struct software_node;
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun /**
246*4882a593Smuzhiyun  * struct software_node_ref_args - Reference property with additional arguments
247*4882a593Smuzhiyun  * @node: Reference to a software node
248*4882a593Smuzhiyun  * @nargs: Number of elements in @args array
249*4882a593Smuzhiyun  * @args: Integer arguments
250*4882a593Smuzhiyun  */
251*4882a593Smuzhiyun struct software_node_ref_args {
252*4882a593Smuzhiyun 	const struct software_node *node;
253*4882a593Smuzhiyun 	unsigned int nargs;
254*4882a593Smuzhiyun 	u64 args[NR_FWNODE_REFERENCE_ARGS];
255*4882a593Smuzhiyun };
256*4882a593Smuzhiyun 
257*4882a593Smuzhiyun /**
258*4882a593Smuzhiyun  * struct property_entry - "Built-in" device property representation.
259*4882a593Smuzhiyun  * @name: Name of the property.
260*4882a593Smuzhiyun  * @length: Length of data making up the value.
261*4882a593Smuzhiyun  * @is_inline: True when the property value is stored inline.
262*4882a593Smuzhiyun  * @type: Type of the data in unions.
263*4882a593Smuzhiyun  * @pointer: Pointer to the property when it is not stored inline.
264*4882a593Smuzhiyun  * @value: Value of the property when it is stored inline.
265*4882a593Smuzhiyun  */
266*4882a593Smuzhiyun struct property_entry {
267*4882a593Smuzhiyun 	const char *name;
268*4882a593Smuzhiyun 	size_t length;
269*4882a593Smuzhiyun 	bool is_inline;
270*4882a593Smuzhiyun 	enum dev_prop_type type;
271*4882a593Smuzhiyun 	union {
272*4882a593Smuzhiyun 		const void *pointer;
273*4882a593Smuzhiyun 		union {
274*4882a593Smuzhiyun 			u8 u8_data[sizeof(u64) / sizeof(u8)];
275*4882a593Smuzhiyun 			u16 u16_data[sizeof(u64) / sizeof(u16)];
276*4882a593Smuzhiyun 			u32 u32_data[sizeof(u64) / sizeof(u32)];
277*4882a593Smuzhiyun 			u64 u64_data[sizeof(u64) / sizeof(u64)];
278*4882a593Smuzhiyun 			const char *str[sizeof(u64) / sizeof(char *)];
279*4882a593Smuzhiyun 		} value;
280*4882a593Smuzhiyun 	};
281*4882a593Smuzhiyun };
282*4882a593Smuzhiyun 
283*4882a593Smuzhiyun /*
284*4882a593Smuzhiyun  * Note: the below initializers for the anonymous union are carefully
285*4882a593Smuzhiyun  * crafted to avoid gcc-4.4.4's problems with initialization of anon unions
286*4882a593Smuzhiyun  * and structs.
287*4882a593Smuzhiyun  */
288*4882a593Smuzhiyun 
289*4882a593Smuzhiyun #define __PROPERTY_ENTRY_ELEMENT_SIZE(_elem_)				\
290*4882a593Smuzhiyun 	sizeof(((struct property_entry *)NULL)->value._elem_[0])
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun #define __PROPERTY_ENTRY_ARRAY_ELSIZE_LEN(_name_, _elsize_, _Type_,	\
293*4882a593Smuzhiyun 					  _val_, _len_)			\
294*4882a593Smuzhiyun (struct property_entry) {						\
295*4882a593Smuzhiyun 	.name = _name_,							\
296*4882a593Smuzhiyun 	.length = (_len_) * (_elsize_),					\
297*4882a593Smuzhiyun 	.type = DEV_PROP_##_Type_,					\
298*4882a593Smuzhiyun 	{ .pointer = _val_ },						\
299*4882a593Smuzhiyun }
300*4882a593Smuzhiyun 
301*4882a593Smuzhiyun #define __PROPERTY_ENTRY_ARRAY_LEN(_name_, _elem_, _Type_, _val_, _len_)\
302*4882a593Smuzhiyun 	__PROPERTY_ENTRY_ARRAY_ELSIZE_LEN(_name_,			\
303*4882a593Smuzhiyun 				__PROPERTY_ENTRY_ELEMENT_SIZE(_elem_),	\
304*4882a593Smuzhiyun 				_Type_, _val_, _len_)
305*4882a593Smuzhiyun 
306*4882a593Smuzhiyun #define PROPERTY_ENTRY_U8_ARRAY_LEN(_name_, _val_, _len_)		\
307*4882a593Smuzhiyun 	__PROPERTY_ENTRY_ARRAY_LEN(_name_, u8_data, U8, _val_, _len_)
308*4882a593Smuzhiyun #define PROPERTY_ENTRY_U16_ARRAY_LEN(_name_, _val_, _len_)		\
309*4882a593Smuzhiyun 	__PROPERTY_ENTRY_ARRAY_LEN(_name_, u16_data, U16, _val_, _len_)
310*4882a593Smuzhiyun #define PROPERTY_ENTRY_U32_ARRAY_LEN(_name_, _val_, _len_)		\
311*4882a593Smuzhiyun 	__PROPERTY_ENTRY_ARRAY_LEN(_name_, u32_data, U32, _val_, _len_)
312*4882a593Smuzhiyun #define PROPERTY_ENTRY_U64_ARRAY_LEN(_name_, _val_, _len_)		\
313*4882a593Smuzhiyun 	__PROPERTY_ENTRY_ARRAY_LEN(_name_, u64_data, U64, _val_, _len_)
314*4882a593Smuzhiyun #define PROPERTY_ENTRY_STRING_ARRAY_LEN(_name_, _val_, _len_)		\
315*4882a593Smuzhiyun 	__PROPERTY_ENTRY_ARRAY_LEN(_name_, str, STRING, _val_, _len_)
316*4882a593Smuzhiyun #define PROPERTY_ENTRY_REF_ARRAY_LEN(_name_, _val_, _len_)		\
317*4882a593Smuzhiyun 	__PROPERTY_ENTRY_ARRAY_ELSIZE_LEN(_name_,			\
318*4882a593Smuzhiyun 				sizeof(struct software_node_ref_args),	\
319*4882a593Smuzhiyun 				REF, _val_, _len_)
320*4882a593Smuzhiyun 
321*4882a593Smuzhiyun #define PROPERTY_ENTRY_U8_ARRAY(_name_, _val_)				\
322*4882a593Smuzhiyun 	PROPERTY_ENTRY_U8_ARRAY_LEN(_name_, _val_, ARRAY_SIZE(_val_))
323*4882a593Smuzhiyun #define PROPERTY_ENTRY_U16_ARRAY(_name_, _val_)				\
324*4882a593Smuzhiyun 	PROPERTY_ENTRY_U16_ARRAY_LEN(_name_, _val_, ARRAY_SIZE(_val_))
325*4882a593Smuzhiyun #define PROPERTY_ENTRY_U32_ARRAY(_name_, _val_)				\
326*4882a593Smuzhiyun 	PROPERTY_ENTRY_U32_ARRAY_LEN(_name_, _val_, ARRAY_SIZE(_val_))
327*4882a593Smuzhiyun #define PROPERTY_ENTRY_U64_ARRAY(_name_, _val_)				\
328*4882a593Smuzhiyun 	PROPERTY_ENTRY_U64_ARRAY_LEN(_name_, _val_, ARRAY_SIZE(_val_))
329*4882a593Smuzhiyun #define PROPERTY_ENTRY_STRING_ARRAY(_name_, _val_)			\
330*4882a593Smuzhiyun 	PROPERTY_ENTRY_STRING_ARRAY_LEN(_name_, _val_, ARRAY_SIZE(_val_))
331*4882a593Smuzhiyun #define PROPERTY_ENTRY_REF_ARRAY(_name_, _val_)			\
332*4882a593Smuzhiyun 	PROPERTY_ENTRY_REF_ARRAY_LEN(_name_, _val_, ARRAY_SIZE(_val_))
333*4882a593Smuzhiyun 
334*4882a593Smuzhiyun #define __PROPERTY_ENTRY_ELEMENT(_name_, _elem_, _Type_, _val_)		\
335*4882a593Smuzhiyun (struct property_entry) {						\
336*4882a593Smuzhiyun 	.name = _name_,							\
337*4882a593Smuzhiyun 	.length = __PROPERTY_ENTRY_ELEMENT_SIZE(_elem_),		\
338*4882a593Smuzhiyun 	.is_inline = true,						\
339*4882a593Smuzhiyun 	.type = DEV_PROP_##_Type_,					\
340*4882a593Smuzhiyun 	{ .value = { ._elem_[0] = _val_ } },				\
341*4882a593Smuzhiyun }
342*4882a593Smuzhiyun 
343*4882a593Smuzhiyun #define PROPERTY_ENTRY_U8(_name_, _val_)				\
344*4882a593Smuzhiyun 	__PROPERTY_ENTRY_ELEMENT(_name_, u8_data, U8, _val_)
345*4882a593Smuzhiyun #define PROPERTY_ENTRY_U16(_name_, _val_)				\
346*4882a593Smuzhiyun 	__PROPERTY_ENTRY_ELEMENT(_name_, u16_data, U16, _val_)
347*4882a593Smuzhiyun #define PROPERTY_ENTRY_U32(_name_, _val_)				\
348*4882a593Smuzhiyun 	__PROPERTY_ENTRY_ELEMENT(_name_, u32_data, U32, _val_)
349*4882a593Smuzhiyun #define PROPERTY_ENTRY_U64(_name_, _val_)				\
350*4882a593Smuzhiyun 	__PROPERTY_ENTRY_ELEMENT(_name_, u64_data, U64, _val_)
351*4882a593Smuzhiyun #define PROPERTY_ENTRY_STRING(_name_, _val_)				\
352*4882a593Smuzhiyun 	__PROPERTY_ENTRY_ELEMENT(_name_, str, STRING, _val_)
353*4882a593Smuzhiyun 
354*4882a593Smuzhiyun #define PROPERTY_ENTRY_BOOL(_name_)		\
355*4882a593Smuzhiyun (struct property_entry) {			\
356*4882a593Smuzhiyun 	.name = _name_,				\
357*4882a593Smuzhiyun 	.is_inline = true,			\
358*4882a593Smuzhiyun }
359*4882a593Smuzhiyun 
360*4882a593Smuzhiyun #define PROPERTY_ENTRY_REF(_name_, _ref_, ...)				\
361*4882a593Smuzhiyun (struct property_entry) {						\
362*4882a593Smuzhiyun 	.name = _name_,							\
363*4882a593Smuzhiyun 	.length = sizeof(struct software_node_ref_args),		\
364*4882a593Smuzhiyun 	.type = DEV_PROP_REF,						\
365*4882a593Smuzhiyun 	{ .pointer = &(const struct software_node_ref_args) {		\
366*4882a593Smuzhiyun 		.node = _ref_,						\
367*4882a593Smuzhiyun 		.nargs = ARRAY_SIZE(((u64[]){ 0, ##__VA_ARGS__ })) - 1,	\
368*4882a593Smuzhiyun 		.args = { __VA_ARGS__ },				\
369*4882a593Smuzhiyun 	} },								\
370*4882a593Smuzhiyun }
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun struct property_entry *
373*4882a593Smuzhiyun property_entries_dup(const struct property_entry *properties);
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun void property_entries_free(const struct property_entry *properties);
376*4882a593Smuzhiyun 
377*4882a593Smuzhiyun int device_add_properties(struct device *dev,
378*4882a593Smuzhiyun 			  const struct property_entry *properties);
379*4882a593Smuzhiyun void device_remove_properties(struct device *dev);
380*4882a593Smuzhiyun 
381*4882a593Smuzhiyun bool device_dma_supported(struct device *dev);
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun enum dev_dma_attr device_get_dma_attr(struct device *dev);
384*4882a593Smuzhiyun 
385*4882a593Smuzhiyun const void *device_get_match_data(struct device *dev);
386*4882a593Smuzhiyun 
387*4882a593Smuzhiyun int device_get_phy_mode(struct device *dev);
388*4882a593Smuzhiyun 
389*4882a593Smuzhiyun void *device_get_mac_address(struct device *dev, char *addr, int alen);
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun int fwnode_get_phy_mode(struct fwnode_handle *fwnode);
392*4882a593Smuzhiyun void *fwnode_get_mac_address(struct fwnode_handle *fwnode,
393*4882a593Smuzhiyun 			     char *addr, int alen);
394*4882a593Smuzhiyun struct fwnode_handle *fwnode_graph_get_next_endpoint(
395*4882a593Smuzhiyun 	const struct fwnode_handle *fwnode, struct fwnode_handle *prev);
396*4882a593Smuzhiyun struct fwnode_handle *
397*4882a593Smuzhiyun fwnode_graph_get_port_parent(const struct fwnode_handle *fwnode);
398*4882a593Smuzhiyun struct fwnode_handle *fwnode_graph_get_remote_port_parent(
399*4882a593Smuzhiyun 	const struct fwnode_handle *fwnode);
400*4882a593Smuzhiyun struct fwnode_handle *fwnode_graph_get_remote_port(
401*4882a593Smuzhiyun 	const struct fwnode_handle *fwnode);
402*4882a593Smuzhiyun struct fwnode_handle *fwnode_graph_get_remote_endpoint(
403*4882a593Smuzhiyun 	const struct fwnode_handle *fwnode);
404*4882a593Smuzhiyun struct fwnode_handle *
405*4882a593Smuzhiyun fwnode_graph_get_remote_node(const struct fwnode_handle *fwnode, u32 port,
406*4882a593Smuzhiyun 			     u32 endpoint);
407*4882a593Smuzhiyun 
fwnode_graph_is_endpoint(struct fwnode_handle * fwnode)408*4882a593Smuzhiyun static inline bool fwnode_graph_is_endpoint(struct fwnode_handle *fwnode)
409*4882a593Smuzhiyun {
410*4882a593Smuzhiyun 	return fwnode_property_present(fwnode, "remote-endpoint");
411*4882a593Smuzhiyun }
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun /*
414*4882a593Smuzhiyun  * Fwnode lookup flags
415*4882a593Smuzhiyun  *
416*4882a593Smuzhiyun  * @FWNODE_GRAPH_ENDPOINT_NEXT: In the case of no exact match, look for the
417*4882a593Smuzhiyun  *				closest endpoint ID greater than the specified
418*4882a593Smuzhiyun  *				one.
419*4882a593Smuzhiyun  * @FWNODE_GRAPH_DEVICE_DISABLED: That the device to which the remote
420*4882a593Smuzhiyun  *				  endpoint of the given endpoint belongs to,
421*4882a593Smuzhiyun  *				  may be disabled.
422*4882a593Smuzhiyun  */
423*4882a593Smuzhiyun #define FWNODE_GRAPH_ENDPOINT_NEXT	BIT(0)
424*4882a593Smuzhiyun #define FWNODE_GRAPH_DEVICE_DISABLED	BIT(1)
425*4882a593Smuzhiyun 
426*4882a593Smuzhiyun struct fwnode_handle *
427*4882a593Smuzhiyun fwnode_graph_get_endpoint_by_id(const struct fwnode_handle *fwnode,
428*4882a593Smuzhiyun 				u32 port, u32 endpoint, unsigned long flags);
429*4882a593Smuzhiyun 
430*4882a593Smuzhiyun #define fwnode_graph_for_each_endpoint(fwnode, child)			\
431*4882a593Smuzhiyun 	for (child = NULL;						\
432*4882a593Smuzhiyun 	     (child = fwnode_graph_get_next_endpoint(fwnode, child)); )
433*4882a593Smuzhiyun 
434*4882a593Smuzhiyun int fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode,
435*4882a593Smuzhiyun 				struct fwnode_endpoint *endpoint);
436*4882a593Smuzhiyun 
437*4882a593Smuzhiyun typedef void *(*devcon_match_fn_t)(struct fwnode_handle *fwnode, const char *id,
438*4882a593Smuzhiyun 				   void *data);
439*4882a593Smuzhiyun 
440*4882a593Smuzhiyun void *fwnode_connection_find_match(struct fwnode_handle *fwnode,
441*4882a593Smuzhiyun 				   const char *con_id, void *data,
442*4882a593Smuzhiyun 				   devcon_match_fn_t match);
443*4882a593Smuzhiyun 
device_connection_find_match(struct device * dev,const char * con_id,void * data,devcon_match_fn_t match)444*4882a593Smuzhiyun static inline void *device_connection_find_match(struct device *dev,
445*4882a593Smuzhiyun 						 const char *con_id, void *data,
446*4882a593Smuzhiyun 						 devcon_match_fn_t match)
447*4882a593Smuzhiyun {
448*4882a593Smuzhiyun 	return fwnode_connection_find_match(dev_fwnode(dev), con_id, data, match);
449*4882a593Smuzhiyun }
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun /* -------------------------------------------------------------------------- */
452*4882a593Smuzhiyun /* Software fwnode support - when HW description is incomplete or missing */
453*4882a593Smuzhiyun 
454*4882a593Smuzhiyun /**
455*4882a593Smuzhiyun  * struct software_node - Software node description
456*4882a593Smuzhiyun  * @name: Name of the software node
457*4882a593Smuzhiyun  * @parent: Parent of the software node
458*4882a593Smuzhiyun  * @properties: Array of device properties
459*4882a593Smuzhiyun  */
460*4882a593Smuzhiyun struct software_node {
461*4882a593Smuzhiyun 	const char *name;
462*4882a593Smuzhiyun 	const struct software_node *parent;
463*4882a593Smuzhiyun 	const struct property_entry *properties;
464*4882a593Smuzhiyun };
465*4882a593Smuzhiyun 
466*4882a593Smuzhiyun bool is_software_node(const struct fwnode_handle *fwnode);
467*4882a593Smuzhiyun const struct software_node *
468*4882a593Smuzhiyun to_software_node(const struct fwnode_handle *fwnode);
469*4882a593Smuzhiyun struct fwnode_handle *software_node_fwnode(const struct software_node *node);
470*4882a593Smuzhiyun 
471*4882a593Smuzhiyun const struct software_node *
472*4882a593Smuzhiyun software_node_find_by_name(const struct software_node *parent,
473*4882a593Smuzhiyun 			   const char *name);
474*4882a593Smuzhiyun 
475*4882a593Smuzhiyun int software_node_register_nodes(const struct software_node *nodes);
476*4882a593Smuzhiyun void software_node_unregister_nodes(const struct software_node *nodes);
477*4882a593Smuzhiyun 
478*4882a593Smuzhiyun int software_node_register_node_group(const struct software_node **node_group);
479*4882a593Smuzhiyun void software_node_unregister_node_group(const struct software_node **node_group);
480*4882a593Smuzhiyun 
481*4882a593Smuzhiyun int software_node_register(const struct software_node *node);
482*4882a593Smuzhiyun void software_node_unregister(const struct software_node *node);
483*4882a593Smuzhiyun 
484*4882a593Smuzhiyun int software_node_notify(struct device *dev, unsigned long action);
485*4882a593Smuzhiyun 
486*4882a593Smuzhiyun struct fwnode_handle *
487*4882a593Smuzhiyun fwnode_create_software_node(const struct property_entry *properties,
488*4882a593Smuzhiyun 			    const struct fwnode_handle *parent);
489*4882a593Smuzhiyun void fwnode_remove_software_node(struct fwnode_handle *fwnode);
490*4882a593Smuzhiyun 
491*4882a593Smuzhiyun int device_add_software_node(struct device *dev, const struct software_node *node);
492*4882a593Smuzhiyun void device_remove_software_node(struct device *dev);
493*4882a593Smuzhiyun 
494*4882a593Smuzhiyun #endif /* _LINUX_PROPERTY_H_ */
495