@@ -591,7 +591,8 @@ def _init_prop(self, name, options):
591
591
592
592
val = self ._prop_val (
593
593
name , prop_type ,
594
- options .get ("required" ) or options .get ("category" ) == "required" )
594
+ options .get ("required" ) or options .get ("category" ) == "required" ,
595
+ options .get ("default" ))
595
596
596
597
if val is None :
597
598
# 'required: false' property that wasn't there, or a property type
@@ -629,8 +630,21 @@ def _init_prop(self, name, options):
629
630
630
631
self .props [name ] = prop
631
632
632
- def _prop_val (self , name , prop_type , required ):
633
+ def _prop_val (self , name , prop_type , required , default ):
633
634
# _init_prop() helper for getting the property's value
635
+ #
636
+ # name:
637
+ # Property name from binding
638
+ #
639
+ # prop_type:
640
+ # Property type from binding (a string like "int")
641
+ #
642
+ # optional:
643
+ # True if the property isn't required to exist
644
+ #
645
+ # default:
646
+ # Default value to use when the property doesn't exist, or None if
647
+ # the binding doesn't give a default value
634
648
635
649
node = self ._node
636
650
prop = node .props .get (name )
@@ -650,6 +664,15 @@ def _prop_val(self, name, prop_type, required):
650
664
"does not appear in {!r}" .format (
651
665
name , self .binding_path , node ))
652
666
667
+ if default is not None :
668
+ # YAML doesn't have a native format for byte arrays. We need to
669
+ # convert those from an array like [0x12, 0x34, ...]. The
670
+ # format has already been checked in
671
+ # _check_prop_type_and_default().
672
+ if prop_type == "uint8-array" :
673
+ return bytes (default )
674
+ return default
675
+
653
676
return None
654
677
655
678
if prop_type == "int" :
@@ -683,14 +706,13 @@ def _prop_val(self, name, prop_type, required):
683
706
.format (name , node .path , node .dt .filename , prop ))
684
707
return None
685
708
686
- if prop_type == "compound" :
687
- # Dummy type for properties like that don't fit any of the patterns
688
- # above, so that we can require all entries in 'properties:' to
689
- # have a 'type: ...'. No Property object is created for it.
690
- return None
691
-
692
- _err ("'{}' in 'properties:' in {} has unknown type '{}'"
693
- .format (name , self .binding_path , prop_type ))
709
+ # prop_type == "compound". We have already checked that the 'type:'
710
+ # value is valid, in _check_binding().
711
+ #
712
+ # 'compound' is a dummy type for properties that don't fit any of the
713
+ # patterns above, so that we can require all entries in 'properties:'
714
+ # to have a 'type: ...'. No Property object is created for it.
715
+ return None
694
716
695
717
def _init_regs (self ):
696
718
# Initializes self.regs
@@ -1315,7 +1337,6 @@ def _check_binding(binding, binding_path):
1315
1337
if prop not in binding :
1316
1338
_err ("missing '{}' property in {}" .format (prop , binding_path ))
1317
1339
1318
- for prop in "title" , "description" :
1319
1340
if not isinstance (binding [prop ], str ) or not binding [prop ]:
1320
1341
_err ("missing, malformed, or empty '{}' in {}"
1321
1342
.format (prop , binding_path ))
@@ -1356,7 +1377,7 @@ def _check_binding_properties(binding, binding_path):
1356
1377
return
1357
1378
1358
1379
ok_prop_keys = {"description" , "type" , "required" , "category" ,
1359
- "constraint" , "enum" , "const" }
1380
+ "constraint" , "enum" , "const" , "default" }
1360
1381
1361
1382
for prop_name , options in binding ["properties" ].items ():
1362
1383
for key in options :
@@ -1373,6 +1394,11 @@ def _check_binding_properties(binding, binding_path):
1373
1394
key , prop_name , binding_path ,
1374
1395
", " .join (ok_prop_keys )))
1375
1396
1397
+ _check_prop_type_and_default (
1398
+ prop_name , options .get ("type" ),
1399
+ options .get ("required" ) or options .get ("category" ) == "required" ,
1400
+ options .get ("default" ), binding_path )
1401
+
1376
1402
if "required" in options and not isinstance (options ["required" ], bool ):
1377
1403
_err ("malformed 'required:' setting '{}' for '{}' in 'properties' "
1378
1404
"in {}, expected true/false"
@@ -1392,6 +1418,67 @@ def _check_binding_properties(binding, binding_path):
1392
1418
.format (binding_path , prop_name ))
1393
1419
1394
1420
1421
+ def _check_prop_type_and_default (prop_name , prop_type , required , default ,
1422
+ binding_path ):
1423
+ # _check_binding() helper. Checks 'type:' and 'default:' for the property
1424
+ # named 'prop_name'
1425
+
1426
+ if prop_type is None :
1427
+ _err ("missing 'type:' for '{}' in 'properties' in {}"
1428
+ .format (prop_name , binding_path ))
1429
+
1430
+ ok_types = {"boolean" , "int" , "array" , "uint8-array" , "string" ,
1431
+ "string-array" , "phandle" , "phandles" , "phandle-array" ,
1432
+ "compound" }
1433
+
1434
+ if prop_type not in ok_types :
1435
+ _err ("'{}' in 'properties:' in {} has unknown type '{}', expected one "
1436
+ "of {}" .format (prop_name , binding_path , prop_type ,
1437
+ ", " .join (ok_types )))
1438
+
1439
+ # Check default
1440
+
1441
+ if default is None :
1442
+ return
1443
+
1444
+ if required :
1445
+ _err ("'default:' for '{}' in 'properties:' in {} is meaningless in "
1446
+ "combination with 'required: true'"
1447
+ .format (prop_name , binding_path ))
1448
+
1449
+ if prop_type in {"boolean" , "compound" , "phandle" , "phandles" ,
1450
+ "phandle-array" }:
1451
+ _err ("'default:' can't be combined with 'type: {}' for '{}' in "
1452
+ "'properties:' in {}" .format (prop_type , prop_name , binding_path ))
1453
+
1454
+ def ok_default ():
1455
+ # Returns True if 'default' is an okay default for the property's type
1456
+
1457
+ if prop_type == "int" and isinstance (default , int ) or \
1458
+ prop_type == "string" and isinstance (default , str ):
1459
+ return True
1460
+
1461
+ # array, uint8-array, or string-array
1462
+
1463
+ if not isinstance (default , list ):
1464
+ return False
1465
+
1466
+ if prop_type == "array" and \
1467
+ all (isinstance (val , int ) for val in default ):
1468
+ return True
1469
+
1470
+ if prop_type == "uint8-array" and \
1471
+ all (isinstance (val , int ) and 0 <= val <= 255 for val in default ):
1472
+ return True
1473
+
1474
+ # string-array
1475
+ return all (isinstance (val , str ) for val in default )
1476
+
1477
+ if not ok_default ():
1478
+ _err ("'default: {}' is invalid for '{}' in 'properties:' in {}, which "
1479
+ "has type {}" .format (default , prop_name , binding_path , prop_type ))
1480
+
1481
+
1395
1482
def _translate (addr , node ):
1396
1483
# Recursively translates 'addr' on 'node' to the address space(s) of its
1397
1484
# parent(s), by looking at 'ranges' properties. Returns the translated
0 commit comments