From c708a17b8e3d3c60b89bcc0b7c33ba37343b301d Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 27 May 2021 21:00:22 +0200 Subject: [PATCH] pm: device: remove CONFIG_PM_MAX_DEVICES When a device is defined a new pointer to a device will be created in the "z_pm_device_slots" region, effectively creating a device array with the same size as the number of system devices. This array is then used by the device PM subsystem to keep track of suspended devices during power transitions. Signed-off-by: Gerard Marull-Paretas --- include/device.h | 18 +++++++++++++++++- include/linker/common-ram.ld | 9 +++++++++ subsys/pm/Kconfig | 5 ----- subsys/pm/device.c | 11 +++-------- 4 files changed, 29 insertions(+), 14 deletions(-) diff --git a/include/device.h b/include/device.h index 8263af3b4e8..1bb12b423a9 100644 --- a/include/device.h +++ b/include/device.h @@ -692,11 +692,27 @@ int device_busy_check(const struct device *chk_dev); #define Z_DEVICE_EXTRA_HANDLES(...) \ FOR_EACH_NONEMPTY_TERM(IDENTITY, (,), __VA_ARGS__) +/* If device power management is enabled, this macro defines a pointer to a + * device in the z_pm_device_slots region. When invoked for each device, this + * will effectively result in a device pointer array with the same size of the + * actual devices list. This is used internally by the device PM subsystem to + * keep track of suspended devices during system power transitions. + */ +#if CONFIG_PM_DEVICE +#define Z_DEVICE_DEFINE_PM_SLOT(dev_name) \ + static const Z_DECL_ALIGN(struct device *) \ + _CONCAT(__pm_device_slot_, DEVICE_NAME_GET(dev_name)) __used \ + __attribute__((__section__(".z_pm_device_slots"))); +#else +#define Z_DEVICE_DEFINE_PM_SLOT(dev_name) +#endif + /* Construct objects that are referenced from struct device. These * include power management and dependency handles. */ #define Z_DEVICE_DEFINE_PRE(node_id, dev_name, ...) \ - Z_DEVICE_DEFINE_HANDLES(node_id, dev_name, __VA_ARGS__) + Z_DEVICE_DEFINE_HANDLES(node_id, dev_name, __VA_ARGS__) \ + Z_DEVICE_DEFINE_PM_SLOT(dev_name) /* Initial build provides a record that associates the device object diff --git a/include/linker/common-ram.ld b/include/linker/common-ram.ld index a1828cf82cf..e8754cf851c 100644 --- a/include/linker/common-ram.ld +++ b/include/linker/common-ram.ld @@ -37,6 +37,15 @@ __device_end = .; } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) +#if CONFIG_PM_DEVICE + SECTION_DATA_PROLOGUE(pm_device_slots, (NOLOAD),) + { + __pm_device_slots_start = .; + KEEP(*(".z_pm_device_slots")); + __pm_device_slots_end = .; + } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) +#endif + SECTION_DATA_PROLOGUE(initshell,,) { /* link in shell initialization objects for all modules that diff --git a/subsys/pm/Kconfig b/subsys/pm/Kconfig index d5b6fdfaaef..1ba64f2da71 100644 --- a/subsys/pm/Kconfig +++ b/subsys/pm/Kconfig @@ -60,11 +60,6 @@ config DEVICE_POWER_MANAGEMENT help This option is deprecated, please use CONFIG_PM_DEVICE instead. -config PM_MAX_DEVICES - int "Max number of devices support power management" - depends on PM_DEVICE - default 15 - config PM_DEVICE_RUNTIME bool "Runtime Device Power Management" depends on PM_DEVICE diff --git a/subsys/pm/device.c b/subsys/pm/device.c index 9c49bd360cb..ec683d43fde 100644 --- a/subsys/pm/device.c +++ b/subsys/pm/device.c @@ -18,10 +18,7 @@ LOG_MODULE_DECLARE(power); extern const struct device __device_start[]; extern const struct device __device_end[]; -/* Indexes into all_devices for devices that support pm, - * in dependency order (later may depend on earlier). - */ -static const struct device *pm_devices[CONFIG_PM_MAX_DEVICES]; +extern const struct device *__pm_device_slots_start[]; /* Number of devices successfully suspended. */ static size_t num_susp; @@ -77,10 +74,8 @@ static int _pm_devices(uint32_t state) return rc; } - pm_devices[num_susp] = dev; + __pm_device_slots_start[num_susp] = dev; num_susp++; - __ASSERT(num_susp < CONFIG_PM_MAX_DEVICES, - "Number of pm devices > CONFIG_PM_MAX_DEVICES"); } } @@ -107,7 +102,7 @@ void pm_resume_devices(void) size_t i; for (i = 0; i < num_susp; i++) { - pm_device_state_set(pm_devices[i], + pm_device_state_set(__pm_device_slots_start[i], PM_DEVICE_STATE_ACTIVE, NULL, NULL); }