diff --git a/drivers/gpio/gpio_atmel_sam3.c b/drivers/gpio/gpio_atmel_sam3.c index 2ba3bfa58b8..b93748c24e3 100644 --- a/drivers/gpio/gpio_atmel_sam3.c +++ b/drivers/gpio/gpio_atmel_sam3.c @@ -284,20 +284,6 @@ static int gpio_sam3_disable_callback(struct device *dev, return 0; } -static int gpio_sam3_suspend_port(struct device *dev) -{ - ARG_UNUSED(dev); - - return -ENOTSUP; -} - -static int gpio_sam3_resume_port(struct device *dev) -{ - ARG_UNUSED(dev); - - return -ENOTSUP; -} - static struct gpio_driver_api gpio_sam3_drv_api_funcs = { .config = gpio_sam3_config, .write = gpio_sam3_write, @@ -305,8 +291,6 @@ static struct gpio_driver_api gpio_sam3_drv_api_funcs = { .set_callback = gpio_sam3_set_callback, .enable_callback = gpio_sam3_enable_callback, .disable_callback = gpio_sam3_disable_callback, - .suspend = gpio_sam3_suspend_port, - .resume = gpio_sam3_resume_port, }; /** diff --git a/drivers/gpio/gpio_dw.c b/drivers/gpio/gpio_dw.c index e7f9056f57a..29c29747d61 100644 --- a/drivers/gpio/gpio_dw.c +++ b/drivers/gpio/gpio_dw.c @@ -34,6 +34,10 @@ #include #endif +#ifdef CONFIG_DEVICE_POWER_MANAGEMENT +#include +#endif + /* * ARC architecture configure IP through IO auxiliary registers. * Other architectures as ARM and x86 configure IP through MMIO registers @@ -286,19 +290,21 @@ static inline int gpio_dw_disable_callback(struct device *port, int access_op, return 0; } -static inline int gpio_dw_suspend_port(struct device *port) +#ifdef CONFIG_DEVICE_POWER_MANAGEMENT +static inline int gpio_dw_suspend_port(struct device *port, int pm_policy) { _gpio_dw_clock_off(port); return 0; } -static inline int gpio_dw_resume_port(struct device *port) +static inline int gpio_dw_resume_port(struct device *port, int pm_policy) { _gpio_dw_clock_on(port); return 0; } +#endif #ifdef CONFIG_SOC_QUARK_SE static inline void gpio_dw_unmask_int(uint32_t mask_addr) @@ -362,8 +368,6 @@ static struct gpio_driver_api api_funcs = { .set_callback = gpio_dw_set_callback, .enable_callback = gpio_dw_enable_callback, .disable_callback = gpio_dw_disable_callback, - .suspend = gpio_dw_suspend_port, - .resume = gpio_dw_resume_port }; #ifdef CONFIG_PCI @@ -456,9 +460,20 @@ struct gpio_dw_config gpio_config_0 = { struct gpio_dw_runtime gpio_0_runtime; +#ifdef CONFIG_DEVICE_POWER_MANAGEMENT +struct device_pm_ops gpio_dev_pm_ops = { + .suspend = gpio_dw_suspend_port, + .resume = gpio_dw_resume_port +}; + +DEVICE_INIT_PM(gpio_dw_0, CONFIG_GPIO_DW_0_NAME, gpio_dw_initialize, + &gpio_dev_pm_ops, &gpio_0_runtime, &gpio_config_0, + SECONDARY, CONFIG_GPIO_DW_INIT_PRIORITY); +#else DEVICE_INIT(gpio_dw_0, CONFIG_GPIO_DW_0_NAME, gpio_dw_initialize, &gpio_0_runtime, &gpio_config_0, SECONDARY, CONFIG_GPIO_DW_INIT_PRIORITY); +#endif #ifdef CONFIG_GPIO_DW_0_IRQ_DIRECT #ifdef CONFIG_IOAPIC @@ -531,9 +546,15 @@ struct gpio_dw_config gpio_dw_config_1 = { struct gpio_dw_runtime gpio_1_runtime; +#ifdef CONFIG_DEVICE_POWER_MANAGEMENT +DEVICE_INIT_PM(gpio_dw_1, CONFIG_GPIO_DW_1_NAME, gpio_dw_initialize, + &gpio_dev_pm_ops, &gpio_1_runtime, &gpio_dw_config_1, + SECONDARY, CONFIG_GPIO_DW_INIT_PRIORITY); +#else DEVICE_INIT(gpio_dw_1, CONFIG_GPIO_DW_1_NAME, gpio_dw_initialize, &gpio_1_runtime, &gpio_dw_config_1, SECONDARY, CONFIG_GPIO_DW_INIT_PRIORITY); +#endif #ifdef CONFIG_GPIO_DW_1_IRQ_DIRECT #ifdef CONFIG_IOAPIC diff --git a/drivers/gpio/gpio_k64.c b/drivers/gpio/gpio_k64.c index 7c05066d277..ba7bfcc5a0a 100644 --- a/drivers/gpio/gpio_k64.c +++ b/drivers/gpio/gpio_k64.c @@ -221,22 +221,6 @@ static int gpio_k64_disable_callback(struct device *dev, } -static int gpio_k64_suspend_port(struct device *dev) -{ - ARG_UNUSED(dev); - - return -ENOTSUP; -} - - -static int gpio_k64_resume_port(struct device *dev) -{ - ARG_UNUSED(dev); - - return -ENOTSUP; -} - - /** * @brief Handler for port interrupts * @param dev Pointer to device structure for driver instance @@ -290,8 +274,6 @@ static struct gpio_driver_api gpio_k64_drv_api_funcs = { .set_callback = gpio_k64_set_callback, .enable_callback = gpio_k64_enable_callback, .disable_callback = gpio_k64_disable_callback, - .suspend = gpio_k64_suspend_port, - .resume = gpio_k64_resume_port, }; diff --git a/drivers/gpio/gpio_mmio.c b/drivers/gpio/gpio_mmio.c index 8824ff590ec..b7a64368ae7 100644 --- a/drivers/gpio/gpio_mmio.c +++ b/drivers/gpio/gpio_mmio.c @@ -277,20 +277,6 @@ static int gpio_mmio_disable_callback(struct device *dev, return -ENOTSUP; } -static int gpio_mmio_suspend_port(struct device *dev) -{ - ARG_UNUSED(dev); - - return -ENOTSUP; -} - -static int gpio_mmio_resume_port(struct device *dev) -{ - ARG_UNUSED(dev); - - return -ENOTSUP; -} - static struct gpio_driver_api gpio_mmio_drv_api_funcs = { .config = gpio_mmio_config, .write = gpio_mmio_write, @@ -298,8 +284,6 @@ static struct gpio_driver_api gpio_mmio_drv_api_funcs = { .set_callback = gpio_mmio_set_callback, .enable_callback = gpio_mmio_enable_callback, .disable_callback = gpio_mmio_disable_callback, - .suspend = gpio_mmio_suspend_port, - .resume = gpio_mmio_resume_port, }; /** diff --git a/drivers/gpio/gpio_pcal9535a.c b/drivers/gpio/gpio_pcal9535a.c index 25bb5b6c167..8b97be62b5e 100644 --- a/drivers/gpio/gpio_pcal9535a.c +++ b/drivers/gpio/gpio_pcal9535a.c @@ -544,24 +544,6 @@ static int gpio_pcal9535a_disable_callback(struct device *dev, return -ENOTSUP; } -static int gpio_pcal9535a_suspend_port(struct device *dev) -{ - if (!_has_i2c_master(dev)) { - return -EINVAL; - } - - return -ENOTSUP; -} - -static int gpio_pcal9535a_resume_port(struct device *dev) -{ - if (!_has_i2c_master(dev)) { - return -EINVAL; - } - - return -ENOTSUP; -} - static struct gpio_driver_api gpio_pcal9535a_drv_api_funcs = { .config = gpio_pcal9535a_config, .write = gpio_pcal9535a_write, @@ -569,8 +551,6 @@ static struct gpio_driver_api gpio_pcal9535a_drv_api_funcs = { .set_callback = gpio_pcal9535a_set_callback, .enable_callback = gpio_pcal9535a_enable_callback, .disable_callback = gpio_pcal9535a_disable_callback, - .suspend = gpio_pcal9535a_suspend_port, - .resume = gpio_pcal9535a_resume_port, }; /** diff --git a/drivers/gpio/gpio_qmsi.c b/drivers/gpio/gpio_qmsi.c index 8467b0b2d50..7d98833463f 100644 --- a/drivers/gpio/gpio_qmsi.c +++ b/drivers/gpio/gpio_qmsi.c @@ -271,16 +271,6 @@ static inline int gpio_qmsi_disable_callback(struct device *port, return 0; } -static inline int gpio_qmsi_suspend_port(struct device *port) -{ - return -ENODEV; -} - -static inline int gpio_qmsi_resume_port(struct device *port) -{ - return -ENODEV; -} - static struct gpio_driver_api api_funcs = { .config = gpio_qmsi_config, .write = gpio_qmsi_write, @@ -288,8 +278,6 @@ static struct gpio_driver_api api_funcs = { .set_callback = gpio_qmsi_set_callback, .enable_callback = gpio_qmsi_enable_callback, .disable_callback = gpio_qmsi_disable_callback, - .suspend = gpio_qmsi_suspend_port, - .resume = gpio_qmsi_resume_port }; int gpio_qmsi_init(struct device *port) diff --git a/drivers/gpio/gpio_sch.c b/drivers/gpio/gpio_sch.c index 2ca29981784..ad1dc91d159 100644 --- a/drivers/gpio/gpio_sch.c +++ b/drivers/gpio/gpio_sch.c @@ -316,16 +316,6 @@ static int gpio_sch_disable_callback(struct device *dev, return 0; } -static int gpio_sch_suspend(struct device *dev) -{ - return 0; -} - -static int gpio_sch_resume(struct device *dev) -{ - return 0; -} - static struct gpio_driver_api gpio_sch_api = { .config = gpio_sch_config, .write = gpio_sch_write, @@ -333,8 +323,6 @@ static struct gpio_driver_api gpio_sch_api = { .set_callback = gpio_sch_set_callback, .enable_callback = gpio_sch_enable_callback, .disable_callback = gpio_sch_disable_callback, - .suspend = gpio_sch_suspend, - .resume = gpio_sch_resume }; int gpio_sch_init(struct device *dev) diff --git a/drivers/gpio/gpio_stm32.c b/drivers/gpio/gpio_stm32.c index 6c1fb39b710..07b6a6e80e1 100644 --- a/drivers/gpio/gpio_stm32.c +++ b/drivers/gpio/gpio_stm32.c @@ -178,20 +178,6 @@ static int gpio_stm32_disable_callback(struct device *dev, return 0; } -static int gpio_stm32_suspend_port(struct device *dev) -{ - ARG_UNUSED(dev); - - return -ENOTSUP; -} - -static int gpio_stm32_resume_port(struct device *dev) -{ - ARG_UNUSED(dev); - - return -ENOTSUP; -} - static struct gpio_driver_api gpio_stm32_driver = { .config = gpio_stm32_config, .write = gpio_stm32_write, @@ -199,8 +185,6 @@ static struct gpio_driver_api gpio_stm32_driver = { .set_callback = gpio_stm32_set_callback, .enable_callback = gpio_stm32_enable_callback, .disable_callback = gpio_stm32_disable_callback, - .suspend = gpio_stm32_suspend_port, - .resume = gpio_stm32_resume_port, }; diff --git a/include/device.h b/include/device.h index f9b7cb2abda..a784c78fbd0 100644 --- a/include/device.h +++ b/include/device.h @@ -87,6 +87,7 @@ extern "C" { * (e.g. CONFIG_KERNEL_INIT_PRIORITY_DEFAULT + 5). */ +#ifndef CONFIG_DEVICE_POWER_MANAGEMENT #define DEVICE_INIT(dev_name, drv_name, init_fn, data, cfg_info, level, prio) \ \ static struct device_config __config_##dev_name __used \ @@ -100,6 +101,88 @@ extern "C" { .config = &(__config_##dev_name), \ .driver_data = data \ } +#else +/** + * @def DEVICE_INIT_PM + * + * @brief create device object and set it up for boot time initialization + * + * @details This macro defines a device object that is automatically + * configured by the kernel during system initialization. + * + * @param dev_name Device name. + * + * @param drv_name The name this instance of the driver exposes to + * the system. + * + * @param init_fn Address to the init function of the driver. + * + * @param device_pm_ops Address to the device_pm_ops structure of the driver. + * + * @param data Pointer to the device's configuration data. + * + * @param cfg_info The address to the structure containing the + * configuration information for this instance of the driver. + * + * @param level The initialization level at which configuration occurs. + * Must be one of the following symbols, which are listed in the order + * they are performed by the kernel: + * + * PRIMARY: Used for devices that have no dependencies, such as those + * that rely solely on hardware present in the processor/SOC. These devices + * cannot use any kernel services during configuration, since they are not + * yet available. + * + * SECONDARY: Used for devices that rely on the initialization of devices + * initialized as part of the PRIMARY level. These devices cannot use any + * kernel services during configuration, since they are not yet available. + * + * NANOKERNEL: Used for devices that require nanokernel services during + * configuration. + * + * MICROKERNEL: Used for devices that require microkernel services during + * configuration. + * + * APPLICATION: Used for application components (i.e. non-kernel components) + * that need automatic configuration. These devices can use all services + * provided by the kernel during configuration. + * + * @param prio The initialization priority of the device, relative to + * other devices of the same initialization level. Specified as an integer + * value in the range 0 to 99; lower values indicate earlier initialization. + * Must be a decimal integer literal without leading zeroes or sign (e.g. 32), + * or an equivalent symbolic name (e.g. \#define MY_INIT_PRIO 32); symbolic + * expressions are *not* permitted + * (e.g. CONFIG_KERNEL_INIT_PRIORITY_DEFAULT + 5). + */ + +#define DEVICE_INIT_PM(dev_name, drv_name, init_fn, device_pm_ops, \ + data, cfg_info, level, prio) \ + \ + static struct device_config __config_##dev_name __used \ + __attribute__((__section__(".devconfig.init"))) = { \ + .name = drv_name, .init = (init_fn), \ + .dev_pm_ops = (device_pm_ops), \ + .config_info = (cfg_info) \ + }; \ + \ + static struct device (__device_##dev_name) __used \ + __attribute__((__section__(".init_" #level STRINGIFY(prio)))) = { \ + .config = &(__config_##dev_name), \ + .driver_data = data \ + } + + /* + * Create a default device_pm_ops for devices that do not call the + * DEVICE_INIT_PM macro so that caller of hook functions + * need not check dev_pm_ops != NULL. + */ +extern struct device_pm_ops device_pm_ops_nop; +#define DEVICE_INIT(dev_name, drv_name, init_fn, data, cfg_info, level, prio) \ + DEVICE_INIT_PM(dev_name, drv_name, init_fn, \ + &device_pm_ops_nop, data, cfg_info, \ + level, prio) +#endif /** * @def DEVICE_NAME_GET @@ -165,6 +248,13 @@ extern "C" { struct device; +#ifdef CONFIG_DEVICE_POWER_MANAGEMENT +struct device_pm_ops { + int (*suspend)(struct device *device, int pm_policy); + int (*resume)(struct device *device, int pm_policy); +}; +#endif + /** * @brief Static device information (In ROM) Per driver instance * @param name name of the device @@ -174,6 +264,9 @@ struct device; struct device_config { char *name; int (*init)(struct device *device); +#ifdef CONFIG_DEVICE_POWER_MANAGEMENT + struct device_pm_ops *dev_pm_ops; +#endif void *config_info; }; @@ -193,6 +286,74 @@ struct device { void _sys_device_do_config_level(int level); struct device* device_get_binding(char *name); +#ifdef CONFIG_DEVICE_POWER_MANAGEMENT +/** + * Device PM functions + */ + +/** + * @brief No-op function to initialize unimplemented pm hooks + * + * This function should be used to initialize device pm hooks + * for which a device has no operation. + * + * @param unused_device + * @param unused_policy + * + * @retval Always returns 0 + */ +int device_pm_nop(struct device *unused_device, int unused_policy); + +/** + * @brief Call the suspend function of a device + * + * Called by the Power Manager application to let the device do + * any policy based PM suspend operations. + * + * @param device Pointer to device structure of the driver instance. + * @param pm_policy PM policy for which this call is made. + * + * @retval 0 If successful. + * @retval -EBUSY If device is busy + * @retval Other negative errno code if failure. + */ +static inline int device_suspend(struct device *device, int pm_policy) +{ + return device->config->dev_pm_ops->suspend(device, pm_policy); +} + +/** + * @brief Call the resume function of a device + * + * Called by the Power Manager application to let the device do + * any policy based PM resume operations. + * + * @param device Pointer to device structure of the driver instance. + * @param pm_policy PM policy for which this call is made. + * + * @retval 0 If successful. + * @retval Negative errno code if failure. + */ +static inline int device_resume(struct device *device, int pm_policy) +{ + return device->config->dev_pm_ops->resume(device, pm_policy); +} + +/** + * @brief Gets the device structure list array and device count + * + * Called by the Power Manager application to get the list of + * device structures associated with the devices in the system. + * The PM app would use this list to create its own sorted list + * based on the order it wishes to suspend or resume the devices. + * + * @param device_list Pointer to receive the device list array + * @param device_count Pointer to receive the device count + */ +void device_list_get(struct device **device_list, int *device_count); + +#endif + /** * Synchronous calls API */ diff --git a/include/gpio.h b/include/gpio.h index b79c393f930..b4407fb0328 100644 --- a/include/gpio.h +++ b/include/gpio.h @@ -150,8 +150,6 @@ typedef int (*gpio_enable_callback_t)(struct device *port, typedef int (*gpio_disable_callback_t)(struct device *port, int access_op, uint32_t pin); -typedef int (*gpio_suspend_port_t)(struct device *port); -typedef int (*gpio_resume_port_t)(struct device *port); struct gpio_driver_api { gpio_config_t config; @@ -160,8 +158,6 @@ struct gpio_driver_api { gpio_set_callback_t set_callback; gpio_enable_callback_t enable_callback; gpio_disable_callback_t disable_callback; - gpio_suspend_port_t suspend; - gpio_resume_port_t resume; }; /** * @endcond @@ -325,31 +321,6 @@ static inline int gpio_port_disable_callback(struct device *port) return api->disable_callback(port, GPIO_ACCESS_BY_PORT, 0); } -/** - * @brief Save the state of the device and make it go to the - * low power state. - * @param port Pointer to the device structure for the driver instance. - */ -static inline int gpio_suspend(struct device *port) -{ - struct gpio_driver_api *api; - - api = (struct gpio_driver_api *) port->driver_api; - return api->suspend(port); -} - -/** - * @brief Restore the state stored during suspend and resume operation. - * @param port Pointer to the device structure for the driver instance. - */ -static inline int gpio_resume(struct device *port) -{ - struct gpio_driver_api *api; - - api = (struct gpio_driver_api *) port->driver_api; - return api->resume(port); -} - #ifdef __cplusplus } #endif diff --git a/include/init.h b/include/init.h index 7adec2f4cf9..56d99cbef9d 100644 --- a/include/init.h +++ b/include/init.h @@ -41,6 +41,12 @@ extern "C" { #define SYS_INIT(init_fn, level, prio) \ DEVICE_INIT(sys_init_##init_fn, "", init_fn, NULL, NULL, level, prio) +#ifdef CONFIG_DEVICE_POWER_MANAGEMENT +#define SYS_INIT_PM(drv_name, init_fn, device_pm_ops, level, prio) \ + DEVICE_INIT_PM(sys_init_##init_fn, drv_name, init_fn, device_pm_ops, \ + NULL, NULL, level, prio) +#endif + #ifdef __cplusplus } #endif diff --git a/kernel/nanokernel/device.c b/kernel/nanokernel/device.c index 0d6856fdac8..e2a597ea8f1 100644 --- a/kernel/nanokernel/device.c +++ b/kernel/nanokernel/device.c @@ -35,6 +35,10 @@ static struct device *config_levels[] = { __device_init_end, }; +#ifdef CONFIG_DEVICE_POWER_MANAGEMENT +struct device_pm_ops device_pm_ops_nop = {device_pm_nop, device_pm_nop}; +#endif + /** * @brief Execute all the device initialization functions at a given level * @@ -81,3 +85,17 @@ struct device *device_get_binding(char *name) return NULL; } + +#ifdef CONFIG_DEVICE_POWER_MANAGEMENT +int device_pm_nop(struct device *unused_device, int unused_policy) +{ + return 0; +} + +void device_list_get(struct device **device_list, int *device_count) +{ + + *device_list = __device_init_start; + *device_count = __device_init_end - __device_init_start; +} +#endif diff --git a/samples/power/power_hooks/prj.conf b/samples/power/power_hooks/prj.conf index 129bd7b3a82..d220f4e0aff 100644 --- a/samples/power/power_hooks/prj.conf +++ b/samples/power/power_hooks/prj.conf @@ -1,4 +1,4 @@ CONFIG_STDOUT_CONSOLE=y CONFIG_SYS_POWER_MANAGEMENT=y -CONFIG_SYS_POWER_LOW_POWER_STATE=y +CONFIG_DEVICE_POWER_MANAGEMENT=y CONFIG_TICKLESS_IDLE=y diff --git a/samples/power/power_mgr/prj.conf b/samples/power/power_mgr/prj.conf index 89ab8d480bc..1bdf85055e5 100644 --- a/samples/power/power_mgr/prj.conf +++ b/samples/power/power_mgr/prj.conf @@ -1,5 +1,7 @@ CONFIG_SYS_POWER_MANAGEMENT=y CONFIG_SYS_POWER_LOW_POWER_STATE=y +CONFIG_DEVICE_POWER_MANAGEMENT=y CONFIG_TICKLESS_IDLE=y CONFIG_RTC=y +CONFIG_GPIO=y CONFIG_STDOUT_CONSOLE=y diff --git a/samples/power/power_mgr/src/main.c b/samples/power/power_mgr/src/main.c index 0a8b9fd4f70..f2b2e6c13fc 100644 --- a/samples/power/power_mgr/src/main.c +++ b/samples/power/power_mgr/src/main.c @@ -24,6 +24,7 @@ #include #define PRINT printk #endif +#include #include #define SLEEPTICKS SECONDS(5) @@ -33,6 +34,15 @@ static int pm_state; /* 1 = LPS; 2 = Device suspend only */ static void quark_low_power(void); static struct device *rtc_dev; static uint32_t start_time, end_time; +static void create_device_list(void); +static void suspend_devices(int pm_policy); +static void resume_devices(int pm_policy); + +#define DEVICE_POLICY_MAX 10 +static struct device *device_list; +static int device_count; +static char device_policy_list[DEVICE_POLICY_MAX]; +static char device_retval[DEVICE_POLICY_MAX]; void main(void) { @@ -49,6 +59,8 @@ void main(void) rtc_enable(rtc_dev); rtc_set_config(rtc_dev, &config); + create_device_list(); + while (1) { task_sleep(SLEEPTICKS); } @@ -79,6 +91,7 @@ static int low_power_state_entry(int32_t ticks) PRINT("\n\nLow power state policy entry!\n"); /* Turn off peripherals/clocks here */ + suspend_devices(SYS_PM_LOW_POWER_STATE); quark_low_power(); @@ -90,6 +103,7 @@ static int device_suspend_only_entry(int32_t ticks) PRINT("Device suspend only policy entry!\n"); /* Turn off peripherals/clocks here */ + suspend_devices(SYS_PM_DEVICE_SUSPEND_ONLY); return SYS_PM_DEVICE_SUSPEND_ONLY; } @@ -120,6 +134,8 @@ int _sys_soc_suspend(int32_t ticks) static void low_power_state_exit(void) { + resume_devices(SYS_PM_LOW_POWER_STATE); + end_time = rtc_read(rtc_dev); PRINT("\nLow power state policy exit!\n"); PRINT("Total Elapsed From Suspend To Resume = %d RTC Cycles\n", @@ -128,6 +144,8 @@ static void low_power_state_exit(void) static void device_suspend_only_exit(void) { + resume_devices(SYS_PM_DEVICE_SUSPEND_ONLY); + end_time = rtc_read(rtc_dev); PRINT("\nDevice suspend only policy exit!\n"); PRINT("Total Elapsed From Suspend To Resume = %d RTC Cycles\n", @@ -164,3 +182,48 @@ static void quark_low_power(void) ::"a"(P_LVL2)); } + +static void suspend_devices(int pm_policy) +{ + int i; + + for (i = 0; i < device_count; i++) { + int idx = device_policy_list[i]; + + device_retval[i] = device_suspend(&device_list[idx], pm_policy); + } +} + +static void resume_devices(int pm_policy) +{ + int i; + + for (i = device_count - 1; i >= 0; i--) { + if (!device_retval[i]) { + int idx = device_policy_list[i]; + + device_resume(&device_list[idx], pm_policy); + } + } +} + +static void create_device_list(void) +{ + int count; + int i; + + /* + * Create a list of devices that will be suspended. + * For the demo we will create a simple list containing + * gpio devices. + */ + device_list_get(&device_list, &count); + + for (i = 0; (i < count) && (device_count < DEVICE_POLICY_MAX); i++) { + if (!strcmp(device_list[i].config->name, CONFIG_GPIO_DW_0_NAME) || + !strcmp(device_list[i].config->name, + CONFIG_GPIO_DW_1_NAME)) { + device_policy_list[device_count++] = i; + } + } +}