Skip to content

Commit e95a44c

Browse files
committed
overlaycheck: Detect unused pinctrl declarations
Nodes under the gpio controller node are treated as potential pin configurations. However, they aren't used unless a device node refers to them via a pinctrl-<n> property (or if they contain a "gpio-hog" property). Add a check that all pin group declarations added by an overlay are at least potentially used by the overlay.
1 parent 669bd08 commit e95a44c

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed

overlaycheck/overlaycheck

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,7 @@ foreach my $overlay (sort(keys(%$source)))
344344
}
345345

346346
dormant_checker($overlay);
347+
pinctrl_checker($overlay);
347348

348349
my $checker = $overlay_checkers{$overlay};
349350
($checker->[0])->($overlay, $checker->[1], $source->{$overlay}) if ($checker);
@@ -941,6 +942,81 @@ sub dormant_checker
941942
}
942943
}
943944

945+
sub pinctrl_checker
946+
{
947+
my ($overlay) = @_;
948+
my $ph;
949+
my $fragnum;
950+
my $fragdepth = 0;
951+
my %pinctrl_refs;
952+
my ($label, $node);
953+
my %gpio_labels;
954+
my %unlabelled_nodes;
955+
956+
die if (!open($ph, '-|', "ovmerge -N ${overlay}-overlay.dts"));
957+
while (my $line = <$ph>)
958+
{
959+
chomp($line);
960+
if ($fragdepth > 0 && $line =~ /\};/) {
961+
$fragdepth--;
962+
next;
963+
}
964+
if ($line =~ /\bfragment@(\d+)\s\{/) {
965+
$fragnum = $1;
966+
$fragdepth = 1;
967+
} elsif ($fragdepth == 1) {
968+
if ($line =~ /target = <&gpio>/) {
969+
$fragdepth++;
970+
} else {
971+
$fragdepth = 0;
972+
}
973+
} elsif ($fragdepth == 2) {
974+
if ($line =~ /__(?:overlay|dormant)__ \{/) {
975+
$fragdepth++;
976+
} else {
977+
$fragdepth = 0;
978+
}
979+
} elsif ($fragdepth == 3) {
980+
# Must cope with multiple subnodes
981+
if ($line =~ /^\s*(?:(\w+): )?([-_0-9a-zA-Z]+) \{/) {
982+
$label = $1 // "";
983+
$node = $2;
984+
$fragdepth++;
985+
if ($label) {
986+
$gpio_labels{$label} = 1;
987+
} else {
988+
$unlabelled_nodes{$node} = 1;
989+
}
990+
} else {
991+
$fragdepth = 0;
992+
}
993+
} elsif ($fragdepth == 4) {
994+
if ($line =~ /^\s*gpio-hog;/) {
995+
delete $unlabelled_nodes{$node};
996+
}
997+
}
998+
999+
# The regex is deliberately relaxed to match pinctrl-0 properties
1000+
# _and_ overrides that target pinctrl-0
1001+
while ($line =~ /\bpinctrl-0(?: |:\d+)=[^<]+<([^>]+)>/g) {
1002+
my $refs = $1;
1003+
while ($refs =~ /&(\w+)/g) {
1004+
$pinctrl_refs{$1} = 1;
1005+
}
1006+
}
1007+
}
1008+
1009+
foreach my $n (sort(keys(%unlabelled_nodes))) {
1010+
error("$overlay: gpio node $node has no label");
1011+
}
1012+
1013+
foreach my $label (sort(keys(%gpio_labels))) {
1014+
if (!$pinctrl_refs{$label}) {
1015+
error("$overlay: gpio node label $label is not referenced");
1016+
}
1017+
}
1018+
}
1019+
9441020
sub error
9451021
{
9461022
print("* $_[0]\n");

0 commit comments

Comments
 (0)