Skip to content

Commit d02a1e9

Browse files
Flavio Ceolinmbolivar-nordic
authored andcommitted
pm: Only resize power domains
Instead of resizing all devices handles, we just resize devices that are power domains. This means that a power domain has to be declared as compatbile with "power-domain" in device tree node. Signed-off-by: Flavio Ceolin <[email protected]>
1 parent acca447 commit d02a1e9

File tree

2 files changed

+78
-1
lines changed

2 files changed

+78
-1
lines changed

kernel/include/kernel_offsets.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
*/
66
#include <device.h>
77

8+
#include <pm/device.h>
9+
810
#ifndef ZEPHYR_KERNEL_INCLUDE_KERNEL_OFFSETS_H_
911
#define ZEPHYR_KERNEL_INCLUDE_KERNEL_OFFSETS_H_
1012

@@ -97,5 +99,17 @@ GEN_ABSOLUTE_SYM(_DEVICE_STRUCT_SIZEOF, sizeof(const struct device));
9799
GEN_ABSOLUTE_SYM(_DEVICE_STRUCT_HANDLES_OFFSET,
98100
offsetof(struct device, handles));
99101

102+
#ifdef CONFIG_PM_DEVICE
103+
GEN_ABSOLUTE_SYM(_DEVICE_STRUCT_PM_OFFSET,
104+
offsetof(struct device, pm));
105+
#endif
106+
107+
/* member offsets in the pm_device structure. Used in image post-processing */
108+
109+
GEN_ABSOLUTE_SYM(_PM_DEVICE_STRUCT_FLAGS_OFFSET,
110+
offsetof(struct pm_device, flags));
111+
112+
GEN_ABSOLUTE_SYM(_PM_DEVICE_FLAG_PD, PM_DEVICE_FLAG_PD);
113+
100114
/* LCOV_EXCL_STOP */
101115
#endif /* ZEPHYR_KERNEL_INCLUDE_KERNEL_OFFSETS_H_ */

scripts/gen_handles.py

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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+
160210
class 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

Comments
 (0)