77
88#define DT_DRV_COMPAT power_domain_gpio
99
10- #include <kernel.h>
11- #include <drivers/gpio.h>
12- #include <pm/device.h>
13- #include <pm/device_runtime.h>
10+ #include <zephyr/ kernel.h>
11+ #include <zephyr/ drivers/gpio.h>
12+ #include <zephyr/ pm/device.h>
13+ #include <zephyr/ pm/device_runtime.h>
1414
15- #include <logging/log.h>
16- LOG_MODULE_REGISTER (power_domain_gpio , LOG_LEVEL_INF );
15+ #include <zephyr/ logging/log.h>
16+ LOG_MODULE_REGISTER (power_domain_gpio , CONFIG_POWER_DOMAIN_LOG_LEVEL );
1717
1818struct pd_gpio_config {
1919 struct gpio_dt_spec enable ;
@@ -22,28 +22,32 @@ struct pd_gpio_config {
2222};
2323
2424struct pd_gpio_data {
25- k_timeout_t last_boot ;
25+ k_timeout_t next_boot ;
2626};
2727
28- const char * actions [] = {
29- [PM_DEVICE_ACTION_RESUME ] = "RESUME" ,
30- [PM_DEVICE_ACTION_SUSPEND ] = "SUSPEND" ,
31- [PM_DEVICE_ACTION_TURN_ON ] = "TURN ON" ,
32- [PM_DEVICE_ACTION_TURN_OFF ] = "TURN OFF"
33- };
34-
35-
3628static int pd_gpio_pm_action (const struct device * dev ,
3729 enum pm_device_action action )
3830{
3931 const struct pd_gpio_config * cfg = dev -> config ;
32+ struct pd_gpio_data * data = dev -> data ;
33+ int64_t next_boot_ticks ;
4034 int rc = 0 ;
4135
36+ /* Validate that blocking API's can be used */
37+ if (!k_can_yield ()) {
38+ LOG_ERR ("Blocking actions cannot run in this context" );
39+ return - ENOTSUP ;
40+ }
41+
4242 switch (action ) {
4343 case PM_DEVICE_ACTION_RESUME :
44+ /* Wait until we can boot again */
45+ k_sleep (data -> next_boot );
4446 /* Switch power on */
4547 gpio_pin_set_dt (& cfg -> enable , 1 );
46- LOG_DBG ("%s is now ON" , dev -> name );
48+ LOG_INF ("%s is now ON" , dev -> name );
49+ /* Wait for domain to come up */
50+ k_sleep (K_USEC (cfg -> startup_delay_us ));
4751 /* Notify supported devices they are now powered */
4852 pm_device_children_action_run (dev , PM_DEVICE_ACTION_TURN_ON , NULL );
4953 break ;
@@ -52,7 +56,10 @@ static int pd_gpio_pm_action(const struct device *dev,
5256 pm_device_children_action_run (dev , PM_DEVICE_ACTION_TURN_OFF , NULL );
5357 /* Switch power off */
5458 gpio_pin_set_dt (& cfg -> enable , 0 );
55- LOG_DBG ("%s is now OFF and powered" , dev -> name );
59+ LOG_INF ("%s is now OFF" , dev -> name );
60+ /* Store next time we can boot */
61+ next_boot_ticks = k_uptime_ticks () + k_us_to_ticks_ceil32 (cfg -> off_on_delay_us );
62+ data -> next_boot = K_TIMEOUT_ABS_TICKS (next_boot_ticks );
5663 break ;
5764 case PM_DEVICE_ACTION_TURN_ON :
5865 /* Actively control the enable pin now that the device is powered */
@@ -74,12 +81,15 @@ static int pd_gpio_pm_action(const struct device *dev,
7481static int pd_gpio_init (const struct device * dev )
7582{
7683 const struct pd_gpio_config * cfg = dev -> config ;
84+ struct pd_gpio_data * data = dev -> data ;
7785 int rc ;
7886
7987 if (!device_is_ready (cfg -> enable .port )) {
8088 LOG_ERR ("GPIO port %s is not ready" , cfg -> enable .port -> name );
8189 return - ENODEV ;
8290 }
91+ /* We can't know how long the domain has been off for before boot */
92+ data -> next_boot = K_TIMEOUT_ABS_US (cfg -> off_on_delay_us );
8393
8494 if (pm_device_on_power_domain (dev )) {
8595 /* Device is unpowered */
0 commit comments