1
2
3
4
5
6
7
8
9
10#include <linux/acpi.h>
11#include <linux/export.h>
12#include <linux/kernel.h>
13#include <linux/of.h>
14#include <linux/of_address.h>
15#include <linux/of_graph.h>
16#include <linux/of_irq.h>
17#include <linux/property.h>
18#include <linux/phy.h>
19
20struct fwnode_handle *dev_fwnode(struct device *dev)
21{
22 return IS_ENABLED(CONFIG_OF) && dev->of_node ?
23 of_fwnode_handle(dev->of_node) : dev->fwnode;
24}
25EXPORT_SYMBOL_GPL(dev_fwnode);
26
27
28
29
30
31
32
33
34bool device_property_present(struct device *dev, const char *propname)
35{
36 return fwnode_property_present(dev_fwnode(dev), propname);
37}
38EXPORT_SYMBOL_GPL(device_property_present);
39
40
41
42
43
44
45bool fwnode_property_present(const struct fwnode_handle *fwnode,
46 const char *propname)
47{
48 bool ret;
49
50 ret = fwnode_call_bool_op(fwnode, property_present, propname);
51 if (ret == false && !IS_ERR_OR_NULL(fwnode) &&
52 !IS_ERR_OR_NULL(fwnode->secondary))
53 ret = fwnode_call_bool_op(fwnode->secondary, property_present,
54 propname);
55 return ret;
56}
57EXPORT_SYMBOL_GPL(fwnode_property_present);
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77int device_property_read_u8_array(struct device *dev, const char *propname,
78 u8 *val, size_t nval)
79{
80 return fwnode_property_read_u8_array(dev_fwnode(dev), propname, val, nval);
81}
82EXPORT_SYMBOL_GPL(device_property_read_u8_array);
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102int device_property_read_u16_array(struct device *dev, const char *propname,
103 u16 *val, size_t nval)
104{
105 return fwnode_property_read_u16_array(dev_fwnode(dev), propname, val, nval);
106}
107EXPORT_SYMBOL_GPL(device_property_read_u16_array);
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127int device_property_read_u32_array(struct device *dev, const char *propname,
128 u32 *val, size_t nval)
129{
130 return fwnode_property_read_u32_array(dev_fwnode(dev), propname, val, nval);
131}
132EXPORT_SYMBOL_GPL(device_property_read_u32_array);
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152int device_property_read_u64_array(struct device *dev, const char *propname,
153 u64 *val, size_t nval)
154{
155 return fwnode_property_read_u64_array(dev_fwnode(dev), propname, val, nval);
156}
157EXPORT_SYMBOL_GPL(device_property_read_u64_array);
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177int device_property_read_string_array(struct device *dev, const char *propname,
178 const char **val, size_t nval)
179{
180 return fwnode_property_read_string_array(dev_fwnode(dev), propname, val, nval);
181}
182EXPORT_SYMBOL_GPL(device_property_read_string_array);
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199int device_property_read_string(struct device *dev, const char *propname,
200 const char **val)
201{
202 return fwnode_property_read_string(dev_fwnode(dev), propname, val);
203}
204EXPORT_SYMBOL_GPL(device_property_read_string);
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221int device_property_match_string(struct device *dev, const char *propname,
222 const char *string)
223{
224 return fwnode_property_match_string(dev_fwnode(dev), propname, string);
225}
226EXPORT_SYMBOL_GPL(device_property_match_string);
227
228static int fwnode_property_read_int_array(const struct fwnode_handle *fwnode,
229 const char *propname,
230 unsigned int elem_size, void *val,
231 size_t nval)
232{
233 int ret;
234
235 ret = fwnode_call_int_op(fwnode, property_read_int_array, propname,
236 elem_size, val, nval);
237 if (ret == -EINVAL && !IS_ERR_OR_NULL(fwnode) &&
238 !IS_ERR_OR_NULL(fwnode->secondary))
239 ret = fwnode_call_int_op(
240 fwnode->secondary, property_read_int_array, propname,
241 elem_size, val, nval);
242
243 return ret;
244}
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264int fwnode_property_read_u8_array(const struct fwnode_handle *fwnode,
265 const char *propname, u8 *val, size_t nval)
266{
267 return fwnode_property_read_int_array(fwnode, propname, sizeof(u8),
268 val, nval);
269}
270EXPORT_SYMBOL_GPL(fwnode_property_read_u8_array);
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290int fwnode_property_read_u16_array(const struct fwnode_handle *fwnode,
291 const char *propname, u16 *val, size_t nval)
292{
293 return fwnode_property_read_int_array(fwnode, propname, sizeof(u16),
294 val, nval);
295}
296EXPORT_SYMBOL_GPL(fwnode_property_read_u16_array);
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316int fwnode_property_read_u32_array(const struct fwnode_handle *fwnode,
317 const char *propname, u32 *val, size_t nval)
318{
319 return fwnode_property_read_int_array(fwnode, propname, sizeof(u32),
320 val, nval);
321}
322EXPORT_SYMBOL_GPL(fwnode_property_read_u32_array);
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342int fwnode_property_read_u64_array(const struct fwnode_handle *fwnode,
343 const char *propname, u64 *val, size_t nval)
344{
345 return fwnode_property_read_int_array(fwnode, propname, sizeof(u64),
346 val, nval);
347}
348EXPORT_SYMBOL_GPL(fwnode_property_read_u64_array);
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368int fwnode_property_read_string_array(const struct fwnode_handle *fwnode,
369 const char *propname, const char **val,
370 size_t nval)
371{
372 int ret;
373
374 ret = fwnode_call_int_op(fwnode, property_read_string_array, propname,
375 val, nval);
376 if (ret == -EINVAL && !IS_ERR_OR_NULL(fwnode) &&
377 !IS_ERR_OR_NULL(fwnode->secondary))
378 ret = fwnode_call_int_op(fwnode->secondary,
379 property_read_string_array, propname,
380 val, nval);
381 return ret;
382}
383EXPORT_SYMBOL_GPL(fwnode_property_read_string_array);
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400int fwnode_property_read_string(const struct fwnode_handle *fwnode,
401 const char *propname, const char **val)
402{
403 int ret = fwnode_property_read_string_array(fwnode, propname, val, 1);
404
405 return ret < 0 ? ret : 0;
406}
407EXPORT_SYMBOL_GPL(fwnode_property_read_string);
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424int fwnode_property_match_string(const struct fwnode_handle *fwnode,
425 const char *propname, const char *string)
426{
427 const char **values;
428 int nval, ret;
429
430 nval = fwnode_property_read_string_array(fwnode, propname, NULL, 0);
431 if (nval < 0)
432 return nval;
433
434 if (nval == 0)
435 return -ENODATA;
436
437 values = kcalloc(nval, sizeof(*values), GFP_KERNEL);
438 if (!values)
439 return -ENOMEM;
440
441 ret = fwnode_property_read_string_array(fwnode, propname, values, nval);
442 if (ret < 0)
443 goto out;
444
445 ret = match_string(values, nval, string);
446 if (ret < 0)
447 ret = -ENODATA;
448out:
449 kfree(values);
450 return ret;
451}
452EXPORT_SYMBOL_GPL(fwnode_property_match_string);
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476int fwnode_property_get_reference_args(const struct fwnode_handle *fwnode,
477 const char *prop, const char *nargs_prop,
478 unsigned int nargs, unsigned int index,
479 struct fwnode_reference_args *args)
480{
481 int ret;
482
483 ret = fwnode_call_int_op(fwnode, get_reference_args, prop, nargs_prop,
484 nargs, index, args);
485
486 if (ret < 0 && !IS_ERR_OR_NULL(fwnode) &&
487 !IS_ERR_OR_NULL(fwnode->secondary))
488 ret = fwnode_call_int_op(fwnode->secondary, get_reference_args,
489 prop, nargs_prop, nargs, index, args);
490
491 return ret;
492}
493EXPORT_SYMBOL_GPL(fwnode_property_get_reference_args);
494
495
496
497
498
499
500
501
502
503
504
505
506struct fwnode_handle *fwnode_find_reference(const struct fwnode_handle *fwnode,
507 const char *name,
508 unsigned int index)
509{
510 struct fwnode_reference_args args;
511 int ret;
512
513 ret = fwnode_property_get_reference_args(fwnode, name, NULL, 0, index,
514 &args);
515 return ret ? ERR_PTR(ret) : args.fwnode;
516}
517EXPORT_SYMBOL_GPL(fwnode_find_reference);
518
519
520
521
522
523
524
525const char *fwnode_get_name(const struct fwnode_handle *fwnode)
526{
527 return fwnode_call_ptr_op(fwnode, get_name);
528}
529EXPORT_SYMBOL_GPL(fwnode_get_name);
530
531
532
533
534
535
536
537
538const char *fwnode_get_name_prefix(const struct fwnode_handle *fwnode)
539{
540 return fwnode_call_ptr_op(fwnode, get_name_prefix);
541}
542
543
544
545
546
547
548
549
550struct fwnode_handle *fwnode_get_parent(const struct fwnode_handle *fwnode)
551{
552 return fwnode_call_ptr_op(fwnode, get_parent);
553}
554EXPORT_SYMBOL_GPL(fwnode_get_parent);
555
556
557
558
559
560
561
562
563
564
565
566
567struct fwnode_handle *fwnode_get_next_parent(struct fwnode_handle *fwnode)
568{
569 struct fwnode_handle *parent = fwnode_get_parent(fwnode);
570
571 fwnode_handle_put(fwnode);
572
573 return parent;
574}
575EXPORT_SYMBOL_GPL(fwnode_get_next_parent);
576
577
578
579
580
581
582
583
584
585
586
587
588struct device *fwnode_get_next_parent_dev(struct fwnode_handle *fwnode)
589{
590 struct device *dev;
591
592 fwnode_handle_get(fwnode);
593 do {
594 fwnode = fwnode_get_next_parent(fwnode);
595 if (!fwnode)
596 return NULL;
597 dev = get_dev_from_fwnode(fwnode);
598 } while (!dev);
599 fwnode_handle_put(fwnode);
600 return dev;
601}
602
603
604
605
606
607
608
609unsigned int fwnode_count_parents(const struct fwnode_handle *fwnode)
610{
611 struct fwnode_handle *__fwnode;
612 unsigned int count;
613
614 __fwnode = fwnode_get_parent(fwnode);
615
616 for (count = 0; __fwnode; count++)
617 __fwnode = fwnode_get_next_parent(__fwnode);
618
619 return count;
620}
621EXPORT_SYMBOL_GPL(fwnode_count_parents);
622
623
624
625
626
627
628
629
630
631
632
633
634
635struct fwnode_handle *fwnode_get_nth_parent(struct fwnode_handle *fwnode,
636 unsigned int depth)
637{
638 unsigned int i;
639
640 fwnode_handle_get(fwnode);
641
642 for (i = 0; i < depth && fwnode; i++)
643 fwnode = fwnode_get_next_parent(fwnode);
644
645 return fwnode;
646}
647EXPORT_SYMBOL_GPL(fwnode_get_nth_parent);
648
649
650
651
652
653
654
655
656
657
658
659bool fwnode_is_ancestor_of(struct fwnode_handle *test_ancestor,
660 struct fwnode_handle *test_child)
661{
662 if (!test_ancestor)
663 return false;
664
665 fwnode_handle_get(test_child);
666 while (test_child) {
667 if (test_child == test_ancestor) {
668 fwnode_handle_put(test_child);
669 return true;
670 }
671 test_child = fwnode_get_next_parent(test_child);
672 }
673 return false;
674}
675
676
677
678
679
680
681struct fwnode_handle *
682fwnode_get_next_child_node(const struct fwnode_handle *fwnode,
683 struct fwnode_handle *child)
684{
685 return fwnode_call_ptr_op(fwnode, get_next_child_node, child);
686}
687EXPORT_SYMBOL_GPL(fwnode_get_next_child_node);
688
689
690
691
692
693
694
695struct fwnode_handle *
696fwnode_get_next_available_child_node(const struct fwnode_handle *fwnode,
697 struct fwnode_handle *child)
698{
699 struct fwnode_handle *next_child = child;
700
701 if (!fwnode)
702 return NULL;
703
704 do {
705 next_child = fwnode_get_next_child_node(fwnode, next_child);
706 if (!next_child)
707 return NULL;
708 } while (!fwnode_device_is_available(next_child));
709
710 return next_child;
711}
712EXPORT_SYMBOL_GPL(fwnode_get_next_available_child_node);
713
714
715
716
717
718
719struct fwnode_handle *device_get_next_child_node(struct device *dev,
720 struct fwnode_handle *child)
721{
722 const struct fwnode_handle *fwnode = dev_fwnode(dev);
723 struct fwnode_handle *next;
724
725
726 next = fwnode_get_next_child_node(fwnode, child);
727 if (next)
728 return next;
729
730
731 if (fwnode && !IS_ERR_OR_NULL(fwnode->secondary))
732 next = fwnode_get_next_child_node(fwnode->secondary, child);
733
734 return next;
735}
736EXPORT_SYMBOL_GPL(device_get_next_child_node);
737
738
739
740
741
742
743struct fwnode_handle *
744fwnode_get_named_child_node(const struct fwnode_handle *fwnode,
745 const char *childname)
746{
747 return fwnode_call_ptr_op(fwnode, get_named_child_node, childname);
748}
749EXPORT_SYMBOL_GPL(fwnode_get_named_child_node);
750
751
752
753
754
755
756struct fwnode_handle *device_get_named_child_node(struct device *dev,
757 const char *childname)
758{
759 return fwnode_get_named_child_node(dev_fwnode(dev), childname);
760}
761EXPORT_SYMBOL_GPL(device_get_named_child_node);
762
763
764
765
766
767
768
769struct fwnode_handle *fwnode_handle_get(struct fwnode_handle *fwnode)
770{
771 if (!fwnode_has_op(fwnode, get))
772 return fwnode;
773
774 return fwnode_call_ptr_op(fwnode, get);
775}
776EXPORT_SYMBOL_GPL(fwnode_handle_get);
777
778
779
780
781
782
783
784
785
786void fwnode_handle_put(struct fwnode_handle *fwnode)
787{
788 fwnode_call_void_op(fwnode, put);
789}
790EXPORT_SYMBOL_GPL(fwnode_handle_put);
791
792
793
794
795
796
797
798
799bool fwnode_device_is_available(const struct fwnode_handle *fwnode)
800{
801 if (!fwnode_has_op(fwnode, device_is_available))
802 return true;
803
804 return fwnode_call_bool_op(fwnode, device_is_available);
805}
806EXPORT_SYMBOL_GPL(fwnode_device_is_available);
807
808
809
810
811
812unsigned int device_get_child_node_count(struct device *dev)
813{
814 struct fwnode_handle *child;
815 unsigned int count = 0;
816
817 device_for_each_child_node(dev, child)
818 count++;
819
820 return count;
821}
822EXPORT_SYMBOL_GPL(device_get_child_node_count);
823
824bool device_dma_supported(struct device *dev)
825{
826 const struct fwnode_handle *fwnode = dev_fwnode(dev);
827
828
829
830
831
832 if (is_of_node(fwnode))
833 return true;
834
835 return acpi_dma_supported(to_acpi_device_node(fwnode));
836}
837EXPORT_SYMBOL_GPL(device_dma_supported);
838
839enum dev_dma_attr device_get_dma_attr(struct device *dev)
840{
841 const struct fwnode_handle *fwnode = dev_fwnode(dev);
842 enum dev_dma_attr attr = DEV_DMA_NOT_SUPPORTED;
843
844 if (is_of_node(fwnode)) {
845 if (of_dma_is_coherent(to_of_node(fwnode)))
846 attr = DEV_DMA_COHERENT;
847 else
848 attr = DEV_DMA_NON_COHERENT;
849 } else
850 attr = acpi_get_dma_attr(to_acpi_device_node(fwnode));
851
852 return attr;
853}
854EXPORT_SYMBOL_GPL(device_get_dma_attr);
855
856
857
858
859
860
861
862
863
864int fwnode_get_phy_mode(struct fwnode_handle *fwnode)
865{
866 const char *pm;
867 int err, i;
868
869 err = fwnode_property_read_string(fwnode, "phy-mode", &pm);
870 if (err < 0)
871 err = fwnode_property_read_string(fwnode,
872 "phy-connection-type", &pm);
873 if (err < 0)
874 return err;
875
876 for (i = 0; i < PHY_INTERFACE_MODE_MAX; i++)
877 if (!strcasecmp(pm, phy_modes(i)))
878 return i;
879
880 return -ENODEV;
881}
882EXPORT_SYMBOL_GPL(fwnode_get_phy_mode);
883
884
885
886
887
888
889
890
891
892int device_get_phy_mode(struct device *dev)
893{
894 return fwnode_get_phy_mode(dev_fwnode(dev));
895}
896EXPORT_SYMBOL_GPL(device_get_phy_mode);
897
898
899
900
901
902
903
904
905
906int fwnode_irq_get(const struct fwnode_handle *fwnode, unsigned int index)
907{
908 struct resource res;
909 int ret;
910
911 if (is_of_node(fwnode))
912 return of_irq_get(to_of_node(fwnode), index);
913
914 ret = acpi_irq_get(ACPI_HANDLE_FWNODE(fwnode), index, &res);
915 if (ret)
916 return ret;
917
918 return res.start;
919}
920EXPORT_SYMBOL(fwnode_irq_get);
921
922
923
924
925
926
927
928
929void __iomem *fwnode_iomap(struct fwnode_handle *fwnode, int index)
930{
931 if (IS_ENABLED(CONFIG_OF_ADDRESS) && is_of_node(fwnode))
932 return of_iomap(to_of_node(fwnode), index);
933
934 return NULL;
935}
936EXPORT_SYMBOL(fwnode_iomap);
937
938
939
940
941
942
943
944
945
946struct fwnode_handle *
947fwnode_graph_get_next_endpoint(const struct fwnode_handle *fwnode,
948 struct fwnode_handle *prev)
949{
950 const struct fwnode_handle *parent;
951 struct fwnode_handle *ep;
952
953
954
955
956
957
958 if (prev)
959 parent = fwnode_graph_get_port_parent(prev);
960 else
961 parent = fwnode;
962
963 ep = fwnode_call_ptr_op(parent, graph_get_next_endpoint, prev);
964
965 if (IS_ERR_OR_NULL(ep) &&
966 !IS_ERR_OR_NULL(parent) && !IS_ERR_OR_NULL(parent->secondary))
967 ep = fwnode_graph_get_next_endpoint(parent->secondary, NULL);
968
969 return ep;
970}
971EXPORT_SYMBOL_GPL(fwnode_graph_get_next_endpoint);
972
973
974
975
976
977
978
979struct fwnode_handle *
980fwnode_graph_get_port_parent(const struct fwnode_handle *endpoint)
981{
982 struct fwnode_handle *port, *parent;
983
984 port = fwnode_get_parent(endpoint);
985 parent = fwnode_call_ptr_op(port, graph_get_port_parent);
986
987 fwnode_handle_put(port);
988
989 return parent;
990}
991EXPORT_SYMBOL_GPL(fwnode_graph_get_port_parent);
992
993
994
995
996
997
998
999struct fwnode_handle *
1000fwnode_graph_get_remote_port_parent(const struct fwnode_handle *fwnode)
1001{
1002 struct fwnode_handle *endpoint, *parent;
1003
1004 endpoint = fwnode_graph_get_remote_endpoint(fwnode);
1005 parent = fwnode_graph_get_port_parent(endpoint);
1006
1007 fwnode_handle_put(endpoint);
1008
1009 return parent;
1010}
1011EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_port_parent);
1012
1013
1014
1015
1016
1017
1018
1019struct fwnode_handle *
1020fwnode_graph_get_remote_port(const struct fwnode_handle *fwnode)
1021{
1022 return fwnode_get_next_parent(fwnode_graph_get_remote_endpoint(fwnode));
1023}
1024EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_port);
1025
1026
1027
1028
1029
1030
1031
1032struct fwnode_handle *
1033fwnode_graph_get_remote_endpoint(const struct fwnode_handle *fwnode)
1034{
1035 return fwnode_call_ptr_op(fwnode, graph_get_remote_endpoint);
1036}
1037EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_endpoint);
1038
1039static bool fwnode_graph_remote_available(struct fwnode_handle *ep)
1040{
1041 struct fwnode_handle *dev_node;
1042 bool available;
1043
1044 dev_node = fwnode_graph_get_remote_port_parent(ep);
1045 available = fwnode_device_is_available(dev_node);
1046 fwnode_handle_put(dev_node);
1047
1048 return available;
1049}
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071struct fwnode_handle *
1072fwnode_graph_get_endpoint_by_id(const struct fwnode_handle *fwnode,
1073 u32 port, u32 endpoint, unsigned long flags)
1074{
1075 struct fwnode_handle *ep, *best_ep = NULL;
1076 unsigned int best_ep_id = 0;
1077 bool endpoint_next = flags & FWNODE_GRAPH_ENDPOINT_NEXT;
1078 bool enabled_only = !(flags & FWNODE_GRAPH_DEVICE_DISABLED);
1079
1080 fwnode_graph_for_each_endpoint(fwnode, ep) {
1081 struct fwnode_endpoint fwnode_ep = { 0 };
1082 int ret;
1083
1084 if (enabled_only && !fwnode_graph_remote_available(ep))
1085 continue;
1086
1087 ret = fwnode_graph_parse_endpoint(ep, &fwnode_ep);
1088 if (ret < 0)
1089 continue;
1090
1091 if (fwnode_ep.port != port)
1092 continue;
1093
1094 if (fwnode_ep.id == endpoint)
1095 return ep;
1096
1097 if (!endpoint_next)
1098 continue;
1099
1100
1101
1102
1103
1104
1105 if (fwnode_ep.id < endpoint ||
1106 (best_ep && best_ep_id < fwnode_ep.id))
1107 continue;
1108
1109 fwnode_handle_put(best_ep);
1110 best_ep = fwnode_handle_get(ep);
1111 best_ep_id = fwnode_ep.id;
1112 }
1113
1114 return best_ep;
1115}
1116EXPORT_SYMBOL_GPL(fwnode_graph_get_endpoint_by_id);
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127unsigned int fwnode_graph_get_endpoint_count(struct fwnode_handle *fwnode,
1128 unsigned long flags)
1129{
1130 struct fwnode_handle *ep;
1131 unsigned int count = 0;
1132
1133 fwnode_graph_for_each_endpoint(fwnode, ep) {
1134 if (flags & FWNODE_GRAPH_DEVICE_DISABLED ||
1135 fwnode_graph_remote_available(ep))
1136 count++;
1137 }
1138
1139 return count;
1140}
1141EXPORT_SYMBOL_GPL(fwnode_graph_get_endpoint_count);
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152int fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode,
1153 struct fwnode_endpoint *endpoint)
1154{
1155 memset(endpoint, 0, sizeof(*endpoint));
1156
1157 return fwnode_call_int_op(fwnode, graph_parse_endpoint, endpoint);
1158}
1159EXPORT_SYMBOL(fwnode_graph_parse_endpoint);
1160
1161const void *device_get_match_data(struct device *dev)
1162{
1163 return fwnode_call_ptr_op(dev_fwnode(dev), device_get_match_data, dev);
1164}
1165EXPORT_SYMBOL_GPL(device_get_match_data);
1166
1167static void *
1168fwnode_graph_devcon_match(struct fwnode_handle *fwnode, const char *con_id,
1169 void *data, devcon_match_fn_t match)
1170{
1171 struct fwnode_handle *node;
1172 struct fwnode_handle *ep;
1173 void *ret;
1174
1175 fwnode_graph_for_each_endpoint(fwnode, ep) {
1176 node = fwnode_graph_get_remote_port_parent(ep);
1177 if (!fwnode_device_is_available(node)) {
1178 fwnode_handle_put(node);
1179 continue;
1180 }
1181
1182 ret = match(node, con_id, data);
1183 fwnode_handle_put(node);
1184 if (ret) {
1185 fwnode_handle_put(ep);
1186 return ret;
1187 }
1188 }
1189 return NULL;
1190}
1191
1192static void *
1193fwnode_devcon_match(struct fwnode_handle *fwnode, const char *con_id,
1194 void *data, devcon_match_fn_t match)
1195{
1196 struct fwnode_handle *node;
1197 void *ret;
1198 int i;
1199
1200 for (i = 0; ; i++) {
1201 node = fwnode_find_reference(fwnode, con_id, i);
1202 if (IS_ERR(node))
1203 break;
1204
1205 ret = match(node, NULL, data);
1206 fwnode_handle_put(node);
1207 if (ret)
1208 return ret;
1209 }
1210
1211 return NULL;
1212}
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225void *fwnode_connection_find_match(struct fwnode_handle *fwnode,
1226 const char *con_id, void *data,
1227 devcon_match_fn_t match)
1228{
1229 void *ret;
1230
1231 if (!fwnode || !match)
1232 return NULL;
1233
1234 ret = fwnode_graph_devcon_match(fwnode, con_id, data, match);
1235 if (ret)
1236 return ret;
1237
1238 return fwnode_devcon_match(fwnode, con_id, data, match);
1239}
1240EXPORT_SYMBOL_GPL(fwnode_connection_find_match);
1241