@@ -458,21 +458,91 @@ static void fixup_phandle_references(struct check *c, struct node *dt,
458
458
struct node * node , struct property * prop )
459
459
{
460
460
struct marker * m = prop -> val .markers ;
461
+ struct fixup * f , * * fp ;
462
+ struct fixup_entry * fe , * * fep ;
461
463
struct node * refnode ;
462
464
cell_t phandle ;
465
+ int has_phandle_refs ;
466
+
467
+ has_phandle_refs = 0 ;
468
+ for_each_marker_of_type (m , REF_PHANDLE ) {
469
+ has_phandle_refs = 1 ;
470
+ break ;
471
+ }
472
+
473
+ if (!has_phandle_refs )
474
+ return ;
463
475
464
476
for_each_marker_of_type (m , REF_PHANDLE ) {
465
477
assert (m -> offset + sizeof (cell_t ) <= prop -> val .len );
466
478
467
479
refnode = get_node_by_ref (dt , m -> ref );
468
- if (! refnode ) {
480
+ if (!refnode && ! symbol_fixup_support ) {
469
481
FAIL (c , "Reference to non-existent node or label \"%s\"\n" ,
470
- m -> ref );
482
+ m -> ref );
471
483
continue ;
472
484
}
473
485
474
- phandle = get_node_phandle (dt , refnode );
475
- * ((cell_t * )(prop -> val .val + m -> offset )) = cpu_to_fdt32 (phandle );
486
+ if (!refnode ) {
487
+ /* allocate fixup entry */
488
+ fe = xmalloc (sizeof (* fe ));
489
+
490
+ fe -> node = node ;
491
+ fe -> prop = prop ;
492
+ fe -> offset = m -> offset ;
493
+ fe -> next = NULL ;
494
+
495
+ /* search for an already existing fixup */
496
+ for_each_fixup (dt , f )
497
+ if (strcmp (f -> ref , m -> ref ) == 0 )
498
+ break ;
499
+
500
+ /* no fixup found, add new */
501
+ if (f == NULL ) {
502
+ f = xmalloc (sizeof (* f ));
503
+ f -> ref = m -> ref ;
504
+ f -> entries = NULL ;
505
+ f -> next = NULL ;
506
+
507
+ /* add it to the tree */
508
+ fp = & dt -> fixups ;
509
+ while (* fp )
510
+ fp = & (* fp )-> next ;
511
+ * fp = f ;
512
+ }
513
+
514
+ /* and now append fixup entry */
515
+ fep = & f -> entries ;
516
+ while (* fep )
517
+ fep = & (* fep )-> next ;
518
+ * fep = fe ;
519
+
520
+ /* mark the entry as unresolved */
521
+ phandle = 0xdeadbeef ;
522
+ } else {
523
+ phandle = get_node_phandle (dt , refnode );
524
+
525
+ /* if it's a plugin, we need to record it */
526
+ if (symbol_fixup_support && dt -> is_plugin ) {
527
+
528
+ /* allocate a new local fixup entry */
529
+ fe = xmalloc (sizeof (* fe ));
530
+
531
+ fe -> node = node ;
532
+ fe -> prop = prop ;
533
+ fe -> offset = m -> offset ;
534
+ fe -> next = NULL ;
535
+
536
+ /* append it to the local fixups */
537
+ fep = & dt -> local_fixups ;
538
+ while (* fep )
539
+ fep = & (* fep )-> next ;
540
+ * fep = fe ;
541
+ }
542
+ }
543
+
544
+ * ((cell_t * )(prop -> val .val + m -> offset )) =
545
+ cpu_to_fdt32 (phandle );
476
546
}
477
547
}
478
548
ERROR (phandle_references , NULL , NULL , fixup_phandle_references , NULL ,
@@ -652,6 +722,45 @@ static void check_obsolete_chosen_interrupt_controller(struct check *c,
652
722
}
653
723
TREE_WARNING (obsolete_chosen_interrupt_controller , NULL );
654
724
725
+ static void check_auto_label_phandles (struct check * c , struct node * dt ,
726
+ struct node * node )
727
+ {
728
+ struct label * l ;
729
+ struct symbol * s , * * sp ;
730
+ int has_label ;
731
+
732
+ if (!symbol_fixup_support )
733
+ return ;
734
+
735
+ has_label = 0 ;
736
+ for_each_label (node -> labels , l ) {
737
+ has_label = 1 ;
738
+ break ;
739
+ }
740
+
741
+ if (!has_label )
742
+ return ;
743
+
744
+ /* force allocation of a phandle for this node */
745
+ (void )get_node_phandle (dt , node );
746
+
747
+ /* add the symbol */
748
+ for_each_label (node -> labels , l ) {
749
+
750
+ s = xmalloc (sizeof (* s ));
751
+ s -> label = l ;
752
+ s -> node = node ;
753
+ s -> next = NULL ;
754
+
755
+ /* add it to the symbols list */
756
+ sp = & dt -> symbols ;
757
+ while (* sp )
758
+ sp = & ((* sp )-> next );
759
+ * sp = s ;
760
+ }
761
+ }
762
+ NODE_WARNING (auto_label_phandles , NULL );
763
+
655
764
static struct check * check_table [] = {
656
765
& duplicate_node_names , & duplicate_property_names ,
657
766
& node_name_chars , & node_name_format , & property_name_chars ,
@@ -670,6 +779,8 @@ static struct check *check_table[] = {
670
779
& avoid_default_addr_size ,
671
780
& obsolete_chosen_interrupt_controller ,
672
781
782
+ & auto_label_phandles ,
783
+
673
784
& always_fail ,
674
785
};
675
786
0 commit comments