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 <flavio.ceolin@intel.com>
This commit is contained in:
parent
acca447948
commit
d02a1e9879
2 changed files with 78 additions and 1 deletions
|
@ -5,6 +5,8 @@
|
|||
*/
|
||||
#include <device.h>
|
||||
|
||||
#include <pm/device.h>
|
||||
|
||||
#ifndef ZEPHYR_KERNEL_INCLUDE_KERNEL_OFFSETS_H_
|
||||
#define ZEPHYR_KERNEL_INCLUDE_KERNEL_OFFSETS_H_
|
||||
|
||||
|
@ -97,5 +99,17 @@ GEN_ABSOLUTE_SYM(_DEVICE_STRUCT_SIZEOF, sizeof(const struct device));
|
|||
GEN_ABSOLUTE_SYM(_DEVICE_STRUCT_HANDLES_OFFSET,
|
||||
offsetof(struct device, handles));
|
||||
|
||||
#ifdef CONFIG_PM_DEVICE
|
||||
GEN_ABSOLUTE_SYM(_DEVICE_STRUCT_PM_OFFSET,
|
||||
offsetof(struct device, pm));
|
||||
#endif
|
||||
|
||||
/* member offsets in the pm_device structure. Used in image post-processing */
|
||||
|
||||
GEN_ABSOLUTE_SYM(_PM_DEVICE_STRUCT_FLAGS_OFFSET,
|
||||
offsetof(struct pm_device, flags));
|
||||
|
||||
GEN_ABSOLUTE_SYM(_PM_DEVICE_FLAG_PD, PM_DEVICE_FLAG_PD);
|
||||
|
||||
/* LCOV_EXCL_STOP */
|
||||
#endif /* ZEPHYR_KERNEL_INCLUDE_KERNEL_OFFSETS_H_ */
|
||||
|
|
|
@ -137,6 +137,7 @@ class Device:
|
|||
# assigned by correlating the device struct handles pointer
|
||||
# value with the addr of a Handles instance.
|
||||
self.__handles = None
|
||||
self.__pm = None
|
||||
|
||||
@property
|
||||
def obj_handles(self):
|
||||
|
@ -157,6 +158,55 @@ class Device:
|
|||
self.__handles = struct.unpack(format, data[offset:offset + size])[0]
|
||||
return self.__handles
|
||||
|
||||
@property
|
||||
def obj_pm(self):
|
||||
"""
|
||||
Returns the value from the device struct pm field, pointing to the
|
||||
pm struct for this device.
|
||||
"""
|
||||
if self.__pm is None:
|
||||
data = symbol_data(self.elf, self.sym)
|
||||
format = "<" if self.elf.little_endian else ">"
|
||||
if self.elf.elfclass == 32:
|
||||
format += "I"
|
||||
size = 4
|
||||
else:
|
||||
format += "Q"
|
||||
size = 8
|
||||
offset = self.ld_constants["_DEVICE_STRUCT_PM_OFFSET"]
|
||||
self.__pm = struct.unpack(format, data[offset:offset + size])[0]
|
||||
return self.__pm
|
||||
|
||||
class PMDevice:
|
||||
"""
|
||||
Represents information about a pm_device object and its references to other objects.
|
||||
"""
|
||||
def __init__(self, elf, ld_constants, sym, addr):
|
||||
self.elf = elf
|
||||
self.ld_constants = ld_constants
|
||||
self.sym = sym
|
||||
self.addr = addr
|
||||
|
||||
# Point to the device instance associated with the pm_device;
|
||||
self.__flags = None
|
||||
|
||||
def is_domain(self):
|
||||
"""
|
||||
Checks if the device that this pm struct belongs is a power domain.
|
||||
"""
|
||||
if self.__flags is None:
|
||||
data = symbol_data(self.elf, self.sym)
|
||||
format = "<" if self.elf.little_endian else ">"
|
||||
if self.elf.elfclass == 32:
|
||||
format += "I"
|
||||
size = 4
|
||||
else:
|
||||
format += "Q"
|
||||
size = 8
|
||||
offset = self.ld_constants["_PM_DEVICE_STRUCT_FLAGS_OFFSET"]
|
||||
self.__flags = struct.unpack(format, data[offset:offset + size])[0]
|
||||
return self.__flags & (1 << self.ld_constants["_PM_DEVICE_FLAG_PD"])
|
||||
|
||||
class Handles:
|
||||
def __init__(self, sym, addr, handles, node):
|
||||
self.sym = sym
|
||||
|
@ -177,6 +227,7 @@ def main():
|
|||
with open(edtser, 'rb') as f:
|
||||
edt = pickle.load(f)
|
||||
|
||||
pm_devices = {}
|
||||
devices = []
|
||||
handles = []
|
||||
# Leading _ are stripped from the stored constant key
|
||||
|
@ -184,6 +235,10 @@ def main():
|
|||
want_constants = set([args.start_symbol,
|
||||
"_DEVICE_STRUCT_SIZEOF",
|
||||
"_DEVICE_STRUCT_HANDLES_OFFSET"])
|
||||
if args.num_dynamic_devices != 0:
|
||||
want_constants.update(["_PM_DEVICE_FLAG_PD",
|
||||
"_DEVICE_STRUCT_PM_OFFSET",
|
||||
"_PM_DEVICE_STRUCT_FLAGS_OFFSET"])
|
||||
ld_constants = dict()
|
||||
|
||||
for section in elf.iter_sections():
|
||||
|
@ -208,6 +263,10 @@ def main():
|
|||
node = edt.dep_ord2node[hdls[0]] if (hdls and hdls[0] != 0) else None
|
||||
handles.append(Handles(sym, addr, hdls, node))
|
||||
debug("handles %s %d %s" % (sym.name, hdls[0] if hdls else -1, node))
|
||||
if sym.name.startswith("__pm_device__") and not sym.name.endswith("_slot"):
|
||||
addr = sym.entry.st_value
|
||||
pm_devices[addr] = PMDevice(elf, ld_constants, sym, addr)
|
||||
debug("pm device %s" % (sym.name,))
|
||||
|
||||
assert len(want_constants) == len(ld_constants), "linker map data incomplete"
|
||||
|
||||
|
@ -339,7 +398,11 @@ def main():
|
|||
else:
|
||||
sup_paths.append('(%s)' % dn.path)
|
||||
hdls.extend(dn.__device.dev_handle for dn in sn.__supports)
|
||||
hdls.extend(DEVICE_HANDLE_NULL for dn in range(args.num_dynamic_devices))
|
||||
|
||||
if args.num_dynamic_devices != 0:
|
||||
pm = pm_devices.get(dev.obj_pm)
|
||||
if pm and pm.is_domain():
|
||||
hdls.extend(DEVICE_HANDLE_NULL for dn in range(args.num_dynamic_devices))
|
||||
|
||||
# Terminate the array with the end symbol
|
||||
hdls.append(DEVICE_HANDLE_ENDS)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue