Add pinctrl support to devtree generator
Adds 2 pin controller properties to certain device
tree nodes if specified in the MRW.
Change-Id: I637e0471524ec806db3e3c9120e29c43dcff4abe
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
diff --git a/gen_devtree.pl b/gen_devtree.pl
index 5c85b43..2853cf4 100755
--- a/gen_devtree.pl
+++ b/gen_devtree.pl
@@ -403,6 +403,13 @@
"CHIP_UNIT");
if ($unitNum == $spiNum) {
$spiMaster{status} = "okay";
+
+ #Add in any pinctrl properties. These would come from the parent
+ #of $spi{SOURCE}, which would be a unit-pingroup-bmc if the
+ #pins for this connection are multi-function.
+ addPinCtrlProps($g_targetObj->getTargetParent($spi->{SOURCE}),
+ \%spiMaster);
+
my $flashName = "flash@".$chipSelect;
$spiMaster{$flashName}{COMMENT} = connectionComment($spi);
@@ -545,6 +552,12 @@
$node{$name}{status} = "okay";
$node{$name}{COMMENT} = connectionComment($uart);
+ #Add in any pinctrl properties. These would come from the parent
+ #of $uart{SOURCE}, which would be a unit-pingroup-bmc if the
+ #pins for this connection are multi-function.
+ addPinCtrlProps($g_targetObj->getTargetParent($uart->{SOURCE}),
+ \%{$node{$name}});
+
push @nodes, { %node };
}
@@ -589,6 +602,12 @@
$node{$name}{COMMENT} = connectionComment($eth);
+ #Add in any pinctrl properties. These would come from the parent
+ #of $eth{SOURCE}, which would be a unit-pingroup-bmc if the
+ #pins for this connection are multi-function.
+ addPinCtrlProps($g_targetObj->getTargetParent($eth->{SOURCE}),
+ \%{$node{$name}});
+
push @nodes, { %node };
}
@@ -708,6 +727,12 @@
my $busNodeName = "i2c$busNum";
$busNodes{$busNodeName}{$busNodeName}{status} = "okay";
$busNodes{$busNodeName}{$busNodeName}{$deviceName} = { %deviceNode };
+
+ #Add in any pinctrl properties. These would come from the parent
+ #of $i2c{SOURCE}, which would be a unit-pingroup-bmc if the
+ #pins for this connection are multi-function.
+ addPinCtrlProps($g_targetObj->getTargetParent($i2c->{SOURCE}),
+ \%{$busNodes{$busNodeName}{$busNodeName}});
}
#Each bus gets its own hash entry in the array
@@ -796,6 +821,63 @@
}
+
+#Adds two pinctrl properties to the device node hash passed in,
+#if specified in the MRW. Pin Control refers to a mechanism for
+#Linux to know which function of a multi-function pin to configure.
+#For example, a pin could either be configured to be a GPIO, or
+#an I2C clock line. The pin function depends on board wiring,
+#so is known by the MRW.
+# $target = the target to get the BMC_DT_PINCTRL_FUNCTS attribute from
+# $node = a hash reference to the device tree node to add the properties to
+sub addPinCtrlProps()
+{
+ my ($target, $node) = @_;
+
+ if (!$g_targetObj->isBadAttribute($target, "BMC_DT_PINCTRL_FUNCS")) {
+ my $attr = $g_targetObj->getAttribute($target,
+ "BMC_DT_PINCTRL_FUNCS");
+
+ my $pinCtrl0Prop = makePinCtrl0PropValue($attr);
+ if ($pinCtrl0Prop ne "") {
+ $node->{"pinctrl-names"} = "default";
+ $node->{"pinctrl-0"} = $pinCtrl0Prop;
+ }
+ }
+}
+
+
+#Constructs the pinctrl-0 property value based on the
+#BMC_DT_PINCTRL_FUNCS attribute passed in.
+# $attr = BMC_DT_PINCTRL_FUNCS attribute value, which is an array
+sub makePinCtrl0PropValue()
+{
+ my $attr = shift;
+ my @entries;
+ my $value = "";
+
+ $attr =~ s/\s//g;
+ my @funcs = split(',', $attr);
+ foreach my $func (@funcs) {
+ if (($func ne "NA") && ($func ne "")) {
+ push @entries, $func;
+ }
+ }
+
+ #<&pinctrl_funcA_default &pinctrl_funcB_default ...>
+ if (scalar @entries) {
+ $value = "<";
+ foreach my $entry (@entries) {
+ $value .= "&pinctrl_".$entry."_default ";
+ }
+ $value =~ s/\s$//; #Remove the trailing space
+ $value .= ">";
+ }
+
+ return $value;
+}
+
+
#Returns a list of compatible fields for the BMC itself.
sub getBMCCompatibles()
{