hc
2024-05-10 23fa18eaa71266feff7ba8d83022d9e1cc83c65a
kernel/include/linux/property.h
....@@ -1,18 +1,16 @@
1
+/* SPDX-License-Identifier: GPL-2.0-only */
12 /*
23 * property.h - Unified device property interface.
34 *
45 * Copyright (C) 2014, Intel Corporation
56 * Authors: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
67 * Mika Westerberg <mika.westerberg@linux.intel.com>
7
- *
8
- * This program is free software; you can redistribute it and/or modify
9
- * it under the terms of the GNU General Public License version 2 as
10
- * published by the Free Software Foundation.
118 */
129
1310 #ifndef _LINUX_PROPERTY_H_
1411 #define _LINUX_PROPERTY_H_
1512
13
+#include <linux/bits.h>
1614 #include <linux/fwnode.h>
1715 #include <linux/types.h>
1816
....@@ -24,7 +22,7 @@
2422 DEV_PROP_U32,
2523 DEV_PROP_U64,
2624 DEV_PROP_STRING,
27
- DEV_PROP_MAX,
25
+ DEV_PROP_REF,
2826 };
2927
3028 enum dev_dma_attr {
....@@ -78,9 +76,21 @@
7876 unsigned int nargs, unsigned int index,
7977 struct fwnode_reference_args *args);
8078
79
+struct fwnode_handle *fwnode_find_reference(const struct fwnode_handle *fwnode,
80
+ const char *name,
81
+ unsigned int index);
82
+
83
+const char *fwnode_get_name(const struct fwnode_handle *fwnode);
84
+const char *fwnode_get_name_prefix(const struct fwnode_handle *fwnode);
8185 struct fwnode_handle *fwnode_get_parent(const struct fwnode_handle *fwnode);
8286 struct fwnode_handle *fwnode_get_next_parent(
8387 struct fwnode_handle *fwnode);
88
+struct device *fwnode_get_next_parent_dev(struct fwnode_handle *fwnode);
89
+unsigned int fwnode_count_parents(const struct fwnode_handle *fwn);
90
+struct fwnode_handle *fwnode_get_nth_parent(struct fwnode_handle *fwn,
91
+ unsigned int depth);
92
+bool fwnode_is_ancestor_of(struct fwnode_handle *test_ancestor,
93
+ struct fwnode_handle *test_child);
8494 struct fwnode_handle *fwnode_get_next_child_node(
8595 const struct fwnode_handle *fwnode, struct fwnode_handle *child);
8696 struct fwnode_handle *fwnode_get_next_available_child_node(
....@@ -163,6 +173,12 @@
163173 return device_property_read_u64_array(dev, propname, NULL, 0);
164174 }
165175
176
+static inline int device_property_string_array_count(struct device *dev,
177
+ const char *propname)
178
+{
179
+ return device_property_read_string_array(dev, propname, NULL, 0);
180
+}
181
+
166182 static inline bool fwnode_property_read_bool(const struct fwnode_handle *fwnode,
167183 const char *propname)
168184 {
....@@ -217,99 +233,140 @@
217233 return fwnode_property_read_u64_array(fwnode, propname, NULL, 0);
218234 }
219235
236
+static inline int
237
+fwnode_property_string_array_count(const struct fwnode_handle *fwnode,
238
+ const char *propname)
239
+{
240
+ return fwnode_property_read_string_array(fwnode, propname, NULL, 0);
241
+}
242
+
243
+struct software_node;
244
+
245
+/**
246
+ * struct software_node_ref_args - Reference property with additional arguments
247
+ * @node: Reference to a software node
248
+ * @nargs: Number of elements in @args array
249
+ * @args: Integer arguments
250
+ */
251
+struct software_node_ref_args {
252
+ const struct software_node *node;
253
+ unsigned int nargs;
254
+ u64 args[NR_FWNODE_REFERENCE_ARGS];
255
+};
256
+
220257 /**
221258 * struct property_entry - "Built-in" device property representation.
222259 * @name: Name of the property.
223260 * @length: Length of data making up the value.
224
- * @is_array: True when the property is an array.
261
+ * @is_inline: True when the property value is stored inline.
225262 * @type: Type of the data in unions.
226
- * @pointer: Pointer to the property (an array of items of the given type).
227
- * @value: Value of the property (when it is a single item of the given type).
263
+ * @pointer: Pointer to the property when it is not stored inline.
264
+ * @value: Value of the property when it is stored inline.
228265 */
229266 struct property_entry {
230267 const char *name;
231268 size_t length;
232
- bool is_array;
269
+ bool is_inline;
233270 enum dev_prop_type type;
234271 union {
272
+ const void *pointer;
235273 union {
236
- const u8 *u8_data;
237
- const u16 *u16_data;
238
- const u32 *u32_data;
239
- const u64 *u64_data;
240
- const char * const *str;
241
- } pointer;
242
- union {
243
- u8 u8_data;
244
- u16 u16_data;
245
- u32 u32_data;
246
- u64 u64_data;
247
- const char *str;
274
+ u8 u8_data[sizeof(u64) / sizeof(u8)];
275
+ u16 u16_data[sizeof(u64) / sizeof(u16)];
276
+ u32 u32_data[sizeof(u64) / sizeof(u32)];
277
+ u64 u64_data[sizeof(u64) / sizeof(u64)];
278
+ const char *str[sizeof(u64) / sizeof(char *)];
248279 } value;
249280 };
250281 };
251282
252283 /*
253
- * Note: the below four initializers for the anonymous union are carefully
284
+ * Note: the below initializers for the anonymous union are carefully
254285 * crafted to avoid gcc-4.4.4's problems with initialization of anon unions
255286 * and structs.
256287 */
257288
258
-#define PROPERTY_ENTRY_INTEGER_ARRAY(_name_, _type_, _Type_, _val_) \
289
+#define __PROPERTY_ENTRY_ELEMENT_SIZE(_elem_) \
290
+ sizeof(((struct property_entry *)NULL)->value._elem_[0])
291
+
292
+#define __PROPERTY_ENTRY_ARRAY_ELSIZE_LEN(_name_, _elsize_, _Type_, \
293
+ _val_, _len_) \
259294 (struct property_entry) { \
260295 .name = _name_, \
261
- .length = ARRAY_SIZE(_val_) * sizeof(_type_), \
262
- .is_array = true, \
296
+ .length = (_len_) * (_elsize_), \
263297 .type = DEV_PROP_##_Type_, \
264
- { .pointer = { ._type_##_data = _val_ } }, \
298
+ { .pointer = _val_ }, \
265299 }
266300
267
-#define PROPERTY_ENTRY_U8_ARRAY(_name_, _val_) \
268
- PROPERTY_ENTRY_INTEGER_ARRAY(_name_, u8, U8, _val_)
269
-#define PROPERTY_ENTRY_U16_ARRAY(_name_, _val_) \
270
- PROPERTY_ENTRY_INTEGER_ARRAY(_name_, u16, U16, _val_)
271
-#define PROPERTY_ENTRY_U32_ARRAY(_name_, _val_) \
272
- PROPERTY_ENTRY_INTEGER_ARRAY(_name_, u32, U32, _val_)
273
-#define PROPERTY_ENTRY_U64_ARRAY(_name_, _val_) \
274
- PROPERTY_ENTRY_INTEGER_ARRAY(_name_, u64, U64, _val_)
301
+#define __PROPERTY_ENTRY_ARRAY_LEN(_name_, _elem_, _Type_, _val_, _len_)\
302
+ __PROPERTY_ENTRY_ARRAY_ELSIZE_LEN(_name_, \
303
+ __PROPERTY_ENTRY_ELEMENT_SIZE(_elem_), \
304
+ _Type_, _val_, _len_)
275305
276
-#define PROPERTY_ENTRY_STRING_ARRAY(_name_, _val_) \
277
-(struct property_entry) { \
278
- .name = _name_, \
279
- .length = ARRAY_SIZE(_val_) * sizeof(const char *), \
280
- .is_array = true, \
281
- .type = DEV_PROP_STRING, \
282
- { .pointer = { .str = _val_ } }, \
306
+#define PROPERTY_ENTRY_U8_ARRAY_LEN(_name_, _val_, _len_) \
307
+ __PROPERTY_ENTRY_ARRAY_LEN(_name_, u8_data, U8, _val_, _len_)
308
+#define PROPERTY_ENTRY_U16_ARRAY_LEN(_name_, _val_, _len_) \
309
+ __PROPERTY_ENTRY_ARRAY_LEN(_name_, u16_data, U16, _val_, _len_)
310
+#define PROPERTY_ENTRY_U32_ARRAY_LEN(_name_, _val_, _len_) \
311
+ __PROPERTY_ENTRY_ARRAY_LEN(_name_, u32_data, U32, _val_, _len_)
312
+#define PROPERTY_ENTRY_U64_ARRAY_LEN(_name_, _val_, _len_) \
313
+ __PROPERTY_ENTRY_ARRAY_LEN(_name_, u64_data, U64, _val_, _len_)
314
+#define PROPERTY_ENTRY_STRING_ARRAY_LEN(_name_, _val_, _len_) \
315
+ __PROPERTY_ENTRY_ARRAY_LEN(_name_, str, STRING, _val_, _len_)
316
+#define PROPERTY_ENTRY_REF_ARRAY_LEN(_name_, _val_, _len_) \
317
+ __PROPERTY_ENTRY_ARRAY_ELSIZE_LEN(_name_, \
318
+ sizeof(struct software_node_ref_args), \
319
+ REF, _val_, _len_)
320
+
321
+#define PROPERTY_ENTRY_U8_ARRAY(_name_, _val_) \
322
+ PROPERTY_ENTRY_U8_ARRAY_LEN(_name_, _val_, ARRAY_SIZE(_val_))
323
+#define PROPERTY_ENTRY_U16_ARRAY(_name_, _val_) \
324
+ PROPERTY_ENTRY_U16_ARRAY_LEN(_name_, _val_, ARRAY_SIZE(_val_))
325
+#define PROPERTY_ENTRY_U32_ARRAY(_name_, _val_) \
326
+ PROPERTY_ENTRY_U32_ARRAY_LEN(_name_, _val_, ARRAY_SIZE(_val_))
327
+#define PROPERTY_ENTRY_U64_ARRAY(_name_, _val_) \
328
+ PROPERTY_ENTRY_U64_ARRAY_LEN(_name_, _val_, ARRAY_SIZE(_val_))
329
+#define PROPERTY_ENTRY_STRING_ARRAY(_name_, _val_) \
330
+ PROPERTY_ENTRY_STRING_ARRAY_LEN(_name_, _val_, ARRAY_SIZE(_val_))
331
+#define PROPERTY_ENTRY_REF_ARRAY(_name_, _val_) \
332
+ PROPERTY_ENTRY_REF_ARRAY_LEN(_name_, _val_, ARRAY_SIZE(_val_))
333
+
334
+#define __PROPERTY_ENTRY_ELEMENT(_name_, _elem_, _Type_, _val_) \
335
+(struct property_entry) { \
336
+ .name = _name_, \
337
+ .length = __PROPERTY_ENTRY_ELEMENT_SIZE(_elem_), \
338
+ .is_inline = true, \
339
+ .type = DEV_PROP_##_Type_, \
340
+ { .value = { ._elem_[0] = _val_ } }, \
283341 }
284342
285
-#define PROPERTY_ENTRY_INTEGER(_name_, _type_, _Type_, _val_) \
286
-(struct property_entry) { \
287
- .name = _name_, \
288
- .length = sizeof(_type_), \
289
- .type = DEV_PROP_##_Type_, \
290
- { .value = { ._type_##_data = _val_ } }, \
291
-}
292
-
293
-#define PROPERTY_ENTRY_U8(_name_, _val_) \
294
- PROPERTY_ENTRY_INTEGER(_name_, u8, U8, _val_)
295
-#define PROPERTY_ENTRY_U16(_name_, _val_) \
296
- PROPERTY_ENTRY_INTEGER(_name_, u16, U16, _val_)
297
-#define PROPERTY_ENTRY_U32(_name_, _val_) \
298
- PROPERTY_ENTRY_INTEGER(_name_, u32, U32, _val_)
299
-#define PROPERTY_ENTRY_U64(_name_, _val_) \
300
- PROPERTY_ENTRY_INTEGER(_name_, u64, U64, _val_)
301
-
302
-#define PROPERTY_ENTRY_STRING(_name_, _val_) \
303
-(struct property_entry) { \
304
- .name = _name_, \
305
- .length = sizeof(const char *), \
306
- .type = DEV_PROP_STRING, \
307
- { .value = { .str = _val_ } }, \
308
-}
343
+#define PROPERTY_ENTRY_U8(_name_, _val_) \
344
+ __PROPERTY_ENTRY_ELEMENT(_name_, u8_data, U8, _val_)
345
+#define PROPERTY_ENTRY_U16(_name_, _val_) \
346
+ __PROPERTY_ENTRY_ELEMENT(_name_, u16_data, U16, _val_)
347
+#define PROPERTY_ENTRY_U32(_name_, _val_) \
348
+ __PROPERTY_ENTRY_ELEMENT(_name_, u32_data, U32, _val_)
349
+#define PROPERTY_ENTRY_U64(_name_, _val_) \
350
+ __PROPERTY_ENTRY_ELEMENT(_name_, u64_data, U64, _val_)
351
+#define PROPERTY_ENTRY_STRING(_name_, _val_) \
352
+ __PROPERTY_ENTRY_ELEMENT(_name_, str, STRING, _val_)
309353
310354 #define PROPERTY_ENTRY_BOOL(_name_) \
311355 (struct property_entry) { \
312356 .name = _name_, \
357
+ .is_inline = true, \
358
+}
359
+
360
+#define PROPERTY_ENTRY_REF(_name_, _ref_, ...) \
361
+(struct property_entry) { \
362
+ .name = _name_, \
363
+ .length = sizeof(struct software_node_ref_args), \
364
+ .type = DEV_PROP_REF, \
365
+ { .pointer = &(const struct software_node_ref_args) { \
366
+ .node = _ref_, \
367
+ .nargs = ARRAY_SIZE(((u64[]){ 0, ##__VA_ARGS__ })) - 1, \
368
+ .args = { __VA_ARGS__ }, \
369
+ } }, \
313370 }
314371
315372 struct property_entry *
....@@ -348,6 +405,28 @@
348405 fwnode_graph_get_remote_node(const struct fwnode_handle *fwnode, u32 port,
349406 u32 endpoint);
350407
408
+static inline bool fwnode_graph_is_endpoint(struct fwnode_handle *fwnode)
409
+{
410
+ return fwnode_property_present(fwnode, "remote-endpoint");
411
+}
412
+
413
+/*
414
+ * Fwnode lookup flags
415
+ *
416
+ * @FWNODE_GRAPH_ENDPOINT_NEXT: In the case of no exact match, look for the
417
+ * closest endpoint ID greater than the specified
418
+ * one.
419
+ * @FWNODE_GRAPH_DEVICE_DISABLED: That the device to which the remote
420
+ * endpoint of the given endpoint belongs to,
421
+ * may be disabled.
422
+ */
423
+#define FWNODE_GRAPH_ENDPOINT_NEXT BIT(0)
424
+#define FWNODE_GRAPH_DEVICE_DISABLED BIT(1)
425
+
426
+struct fwnode_handle *
427
+fwnode_graph_get_endpoint_by_id(const struct fwnode_handle *fwnode,
428
+ u32 port, u32 endpoint, unsigned long flags);
429
+
351430 #define fwnode_graph_for_each_endpoint(fwnode, child) \
352431 for (child = NULL; \
353432 (child = fwnode_graph_get_next_endpoint(fwnode, child)); )
....@@ -355,4 +434,61 @@
355434 int fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode,
356435 struct fwnode_endpoint *endpoint);
357436
437
+typedef void *(*devcon_match_fn_t)(struct fwnode_handle *fwnode, const char *id,
438
+ void *data);
439
+
440
+void *fwnode_connection_find_match(struct fwnode_handle *fwnode,
441
+ const char *con_id, void *data,
442
+ devcon_match_fn_t match);
443
+
444
+static inline void *device_connection_find_match(struct device *dev,
445
+ const char *con_id, void *data,
446
+ devcon_match_fn_t match)
447
+{
448
+ return fwnode_connection_find_match(dev_fwnode(dev), con_id, data, match);
449
+}
450
+
451
+/* -------------------------------------------------------------------------- */
452
+/* Software fwnode support - when HW description is incomplete or missing */
453
+
454
+/**
455
+ * struct software_node - Software node description
456
+ * @name: Name of the software node
457
+ * @parent: Parent of the software node
458
+ * @properties: Array of device properties
459
+ */
460
+struct software_node {
461
+ const char *name;
462
+ const struct software_node *parent;
463
+ const struct property_entry *properties;
464
+};
465
+
466
+bool is_software_node(const struct fwnode_handle *fwnode);
467
+const struct software_node *
468
+to_software_node(const struct fwnode_handle *fwnode);
469
+struct fwnode_handle *software_node_fwnode(const struct software_node *node);
470
+
471
+const struct software_node *
472
+software_node_find_by_name(const struct software_node *parent,
473
+ const char *name);
474
+
475
+int software_node_register_nodes(const struct software_node *nodes);
476
+void software_node_unregister_nodes(const struct software_node *nodes);
477
+
478
+int software_node_register_node_group(const struct software_node **node_group);
479
+void software_node_unregister_node_group(const struct software_node **node_group);
480
+
481
+int software_node_register(const struct software_node *node);
482
+void software_node_unregister(const struct software_node *node);
483
+
484
+int software_node_notify(struct device *dev, unsigned long action);
485
+
486
+struct fwnode_handle *
487
+fwnode_create_software_node(const struct property_entry *properties,
488
+ const struct fwnode_handle *parent);
489
+void fwnode_remove_software_node(struct fwnode_handle *fwnode);
490
+
491
+int device_add_software_node(struct device *dev, const struct software_node *node);
492
+void device_remove_software_node(struct device *dev);
493
+
358494 #endif /* _LINUX_PROPERTY_H_ */