@@ -137,6 +137,7 @@ def __init__(self, elf, ld_constants, sym, addr):
137137 # assigned by correlating the device struct handles pointer
138138 # value with the addr of a Handles instance.
139139 self .__handles = None
140+ self .__pm = None
140141
141142 @property
142143 def obj_handles (self ):
@@ -157,6 +158,55 @@ def obj_handles(self):
157158 self .__handles = struct .unpack (format , data [offset :offset + size ])[0 ]
158159 return self .__handles
159160
161+ @property
162+ def obj_pm (self ):
163+ """
164+ Returns the value from the device struct pm field, pointing to the
165+ pm struct for this device.
166+ """
167+ if self .__pm is None :
168+ data = symbol_data (self .elf , self .sym )
169+ format = "<" if self .elf .little_endian else ">"
170+ if self .elf .elfclass == 32 :
171+ format += "I"
172+ size = 4
173+ else :
174+ format += "Q"
175+ size = 8
176+ offset = self .ld_constants ["_DEVICE_STRUCT_PM_OFFSET" ]
177+ self .__pm = struct .unpack (format , data [offset :offset + size ])[0 ]
178+ return self .__pm
179+
180+ class PMDevice :
181+ """
182+ Represents information about a pm_device object and its references to other objects.
183+ """
184+ def __init__ (self , elf , ld_constants , sym , addr ):
185+ self .elf = elf
186+ self .ld_constants = ld_constants
187+ self .sym = sym
188+ self .addr = addr
189+
190+ # Point to the device instance associated with the pm_device;
191+ self .__flags = None
192+
193+ def is_domain (self ):
194+ """
195+ Checks if the device that this pm struct belongs is a power domain.
196+ """
197+ if self .__flags is None :
198+ data = symbol_data (self .elf , self .sym )
199+ format = "<" if self .elf .little_endian else ">"
200+ if self .elf .elfclass == 32 :
201+ format += "I"
202+ size = 4
203+ else :
204+ format += "Q"
205+ size = 8
206+ offset = self .ld_constants ["_PM_DEVICE_STRUCT_FLAGS_OFFSET" ]
207+ self .__flags = struct .unpack (format , data [offset :offset + size ])[0 ]
208+ return self .__flags & (1 << self .ld_constants ["_PM_DEVICE_FLAG_PD" ])
209+
160210class Handles :
161211 def __init__ (self , sym , addr , handles , node ):
162212 self .sym = sym
@@ -177,13 +227,18 @@ def main():
177227 with open (edtser , 'rb' ) as f :
178228 edt = pickle .load (f )
179229
230+ pm_devices = {}
180231 devices = []
181232 handles = []
182233 # Leading _ are stripped from the stored constant key
183234
184235 want_constants = set ([args .start_symbol ,
185236 "_DEVICE_STRUCT_SIZEOF" ,
186237 "_DEVICE_STRUCT_HANDLES_OFFSET" ])
238+ if args .num_dynamic_devices != 0 :
239+ want_constants .update (["_PM_DEVICE_FLAG_PD" ,
240+ "_DEVICE_STRUCT_PM_OFFSET" ,
241+ "_PM_DEVICE_STRUCT_FLAGS_OFFSET" ])
187242 ld_constants = dict ()
188243
189244 for section in elf .iter_sections ():
@@ -208,6 +263,10 @@ def main():
208263 node = edt .dep_ord2node [hdls [0 ]] if (hdls and hdls [0 ] != 0 ) else None
209264 handles .append (Handles (sym , addr , hdls , node ))
210265 debug ("handles %s %d %s" % (sym .name , hdls [0 ] if hdls else - 1 , node ))
266+ if sym .name .startswith ("__pm_device__" ) and not sym .name .endswith ("_slot" ):
267+ addr = sym .entry .st_value
268+ pm_devices [addr ] = PMDevice (elf , ld_constants , sym , addr )
269+ debug ("pm device %s" % (sym .name ,))
211270
212271 assert len (want_constants ) == len (ld_constants ), "linker map data incomplete"
213272
@@ -339,7 +398,11 @@ def main():
339398 else :
340399 sup_paths .append ('(%s)' % dn .path )
341400 hdls .extend (dn .__device .dev_handle for dn in sn .__supports )
342- hdls .extend (DEVICE_HANDLE_NULL for dn in range (args .num_dynamic_devices ))
401+
402+ if args .num_dynamic_devices != 0 :
403+ pm = pm_devices .get (dev .obj_pm )
404+ if pm and pm .is_domain ():
405+ hdls .extend (DEVICE_HANDLE_NULL for dn in range (args .num_dynamic_devices ))
343406
344407 # Terminate the array with the end symbol
345408 hdls .append (DEVICE_HANDLE_ENDS )
0 commit comments