@@ -509,6 +509,7 @@ def _init_nodes(self):
509509 # run them separately
510510 node ._init_props ()
511511 node ._init_interrupts ()
512+ node ._init_clock_outputs ()
512513 node ._init_gpio_ranges ()
513514
514515 for node in self .nodes :
@@ -783,6 +784,16 @@ class Node:
783784 aliases:
784785 A list of aliases for the node. This is fetched from the /aliases node.
785786
787+ clocks:
788+ A list of ControllerAndData objects for the clock inputs on the
789+ node, sorted by index. The list is empty if the node does not have a
790+ clocks property.
791+
792+ clock_outputs:
793+ A list of ControllerAndData objects for the clock outputs on the
794+ node, sorted by index. The list is empty if the node does not have a
795+ #clock-cells property.
796+
786797 interrupts:
787798 A list of ControllerAndData objects for the interrupts generated by the
788799 node. The list is empty if the node does not generate interrupts.
@@ -947,6 +958,14 @@ def bus(self):
947958
948959 return None
949960
961+ @property
962+ def clocks (self ):
963+ "See the class docstring"
964+
965+ if "clocks" not in self .props :
966+ return []
967+ return self .props ["clocks" ].val
968+
950969 @property
951970 def on_bus (self ):
952971 "See the class docstring"
@@ -1289,6 +1308,84 @@ def _init_gpio_ranges(self):
12891308 prop_value .controller .pinctrl_gpio_ranges = []
12901309 prop_value .controller .pinctrl_gpio_ranges .append (entry )
12911310
1311+ def _init_clock_outputs_append_entry (self , clock_index ,
1312+ clock_outputs_name_indices , clock_output_names ,
1313+ clock_frequency , clock_accuracy ):
1314+ # Append entry to clock_outputs
1315+
1316+ entry = ControllerAndData ()
1317+ entry .node = self
1318+ entry .controller = self
1319+ entry .data = {}
1320+ clock_output_name_index = clock_outputs_name_indices [clock_index ]
1321+ if clock_output_name_index is None :
1322+ entry .name = None
1323+ else :
1324+ entry .name = clock_output_names [clock_output_name_index ]
1325+ if clock_frequency is not None :
1326+ entry .data ["clock-frequency" ] = clock_frequency
1327+ if clock_accuracy is not None :
1328+ entry .data ["clock-accuracy" ] = clock_accuracy
1329+ self .clock_outputs .append (entry )
1330+
1331+ def _init_clock_outputs (self ):
1332+ # Initialize self.clock_outputs
1333+
1334+ self .clock_outputs = []
1335+
1336+ node = self ._node
1337+ if "#clock-cells" not in node .props :
1338+ return
1339+
1340+ clock_cells = node .props ["#clock-cells" ].to_num ()
1341+
1342+ if "clock-output-names" in node .props :
1343+ clock_output_names = node .props .get ("clock-output-names" ) \
1344+ .to_strings ()
1345+ clock_count = len (clock_output_names )
1346+ else :
1347+ clock_output_names = []
1348+ if clock_cells == 0 :
1349+ # clock-cells of 0 indicates one clock
1350+ clock_count = 1
1351+ else :
1352+ # unknown number of output clocks -> assume one
1353+ clock_count = 1
1354+ self .edt ._warn ("no clock-output-names property in clock "
1355+ "provider {!r} - assuming one clock output" .format (node ))
1356+
1357+ if "clock-indices" in node .props :
1358+ clock_indices = clock_indices .to_nums ()
1359+ if not clock_output_names :
1360+ _err ("clock-indices ({}) given without clock-output-names"
1361+ " in clock provider {!r}." .format (clock_indices , self .node ))
1362+ if len (clock_output_names ) != len (clock_indices ):
1363+ _err ("clock-output-names count ({}) does not match"
1364+ " clock-indices count ({}) in clock provider {!r}."
1365+ .format (len (clock_output_names ), len (clock_indices ),
1366+ self .node ))
1367+ # Increase clock count in case there is a higher clock index
1368+ clock_count = max (clock_count , max (clock_indices ) + 1 )
1369+ else :
1370+ clock_indices = None
1371+
1372+ if "clock-frequency" in node .props :
1373+ clock_frequency = node .props .get ("clock-frequency" ).to_num ()
1374+ else :
1375+ clock_frequency = None
1376+
1377+ if "clock-accuracy" in node .props :
1378+ clock_accuracy = node .props .get ("clock-accuracy" ).to_num ()
1379+ else :
1380+ clock_accuracy = None
1381+
1382+ clock_outputs_name_indices = _clock_outputs_name_indices (clock_count ,
1383+ clock_indices , clock_output_names )
1384+ for clock_index in range (0 , clock_count ):
1385+ self ._init_clock_outputs_append_entry (clock_index ,
1386+ clock_outputs_name_indices , clock_output_names ,
1387+ clock_frequency , clock_accuracy )
1388+
12921389 def _init_regs (self ):
12931390 # Initializes self.regs
12941391
@@ -2185,6 +2282,25 @@ def _add_names(node, names_ident, objs):
21852282 obj .name = None
21862283
21872284
2285+ def _clock_outputs_name_indices (clock_count , clock_indices , clock_output_names ):
2286+ # Create a table that indexes to clock output name by clock output index
2287+
2288+ if clock_indices is not None :
2289+ # Make full output name indices table from sparse table given by DTS
2290+ clock_outputs_name_indices = [None for x in range (0 , clock_count )]
2291+ for clock_output_name_index , clock_index in enumerate (clock_indices ):
2292+ clock_outputs_name_indices [clock_index ] = clock_output_name_index
2293+ else :
2294+ clock_outputs_name_indices = []
2295+ for clock_index in range (0 , clock_count ):
2296+ if clock_index < len (clock_output_names ):
2297+ clock_outputs_name_indices .append (clock_index )
2298+ else :
2299+ clock_outputs_name_indices .append (None )
2300+
2301+ return clock_outputs_name_indices
2302+
2303+
21882304def _pincfg_check_type (pincfg_node , prop ):
21892305 # Check pin configuration property type to be inline with expectations.
21902306 # Bindings may specify different types for certain properties.
0 commit comments