12
12
#include <errno.h>
13
13
#include <zephyr/sys/util.h>
14
14
#include <zephyr/irq.h>
15
+ #include <zephyr/pm/device.h>
16
+ #include <zephyr/pm/device_runtime.h>
15
17
16
18
/* Zephyr GPIO header must be included after driver, due to symbol conflicts
17
19
* for GPIO_INPUT and GPIO_OUTPUT between preprocessor macros in the Zephyr
@@ -56,8 +58,12 @@ struct gpio_siwx91x_port_data {
56
58
struct gpio_driver_data common ;
57
59
/* port ISR callback routine address */
58
60
sys_slist_t callbacks ;
61
+ /* stores the direction of each pin */
62
+ uint8_t pin_direction [MAX_PIN_COUNT ];
59
63
};
60
64
65
+ static int gpio_siwx91x_port_pm_action (const struct device * port , enum pm_device_action action );
66
+
61
67
/* Functions */
62
68
static int gpio_siwx91x_pin_configure (const struct device * dev , gpio_pin_t pin , gpio_flags_t flags )
63
69
{
@@ -295,6 +301,34 @@ static inline int gpio_siwx91x_init_port(const struct device *port)
295
301
__ASSERT (cfg -> port < MAX_PORT_COUNT , "Too many ports" );
296
302
data -> ports [cfg -> port ] = port ;
297
303
304
+ return pm_device_driver_init (port , gpio_siwx91x_port_pm_action );
305
+ }
306
+
307
+ static int gpio_siwx91x_port_pm_action (const struct device * port , enum pm_device_action action )
308
+ {
309
+ const struct gpio_siwx91x_port_config * config = port -> config ;
310
+ struct gpio_siwx91x_port_data * data = port -> data ;
311
+
312
+ switch (action ) {
313
+ case PM_DEVICE_ACTION_RESUME :
314
+ for (int pin = 0 ; pin < MAX_PIN_COUNT ; ++ pin ) {
315
+ if (config -> common .port_pin_mask & BIT (pin )) {
316
+ sl_si91x_gpio_set_pin_direction (config -> hal_port , pin ,
317
+ data -> pin_direction [pin ]);
318
+ }
319
+ }
320
+ break ;
321
+ case PM_DEVICE_ACTION_SUSPEND :
322
+ for (int pin = 0 ; pin < MAX_PIN_COUNT ; ++ pin ) {
323
+ if (config -> common .port_pin_mask & BIT (pin )) {
324
+ data -> pin_direction [pin ] =
325
+ sl_si91x_gpio_get_pin_direction (config -> hal_port , pin );
326
+ }
327
+ }
328
+ break ;
329
+ default :
330
+ return - ENOTSUP ;
331
+ }
298
332
return 0 ;
299
333
}
300
334
@@ -361,16 +395,17 @@ static DEVICE_API(gpio, gpio_siwx91x_api) = {
361
395
}; \
362
396
static struct gpio_siwx91x_port_data gpio_siwx91x_port_data##n; \
363
397
\
364
- DEVICE_DT_DEFINE(n, gpio_siwx91x_init_port, NULL, &gpio_siwx91x_port_data##n, \
365
- &gpio_siwx91x_port_config##n, PRE_KERNEL_1, CONFIG_GPIO_INIT_PRIORITY, \
366
- &gpio_siwx91x_api);
398
+ PM_DEVICE_DT_INST_DEFINE(n, gpio_siwx91x_port_pm_action); \
399
+ DEVICE_DT_DEFINE(n, gpio_siwx91x_init_port, PM_DEVICE_DT_INST_GET(n), \
400
+ &gpio_siwx91x_port_data##n, &gpio_siwx91x_port_config##n, PRE_KERNEL_1, \
401
+ CONFIG_GPIO_INIT_PRIORITY, &gpio_siwx91x_api);
367
402
368
403
#define CONFIGURE_SHARED_INTERRUPT (node_id , prop , idx ) \
369
404
IRQ_CONNECT(DT_IRQ_BY_IDX(node_id, idx, irq), DT_IRQ_BY_IDX(node_id, idx, priority), \
370
405
gpio_siwx91x_isr, DEVICE_DT_GET(node_id), 0); \
371
406
irq_enable(DT_IRQ_BY_IDX(node_id, idx, irq));
372
407
373
- static DEVICE_API (gpio , gpio_siwx91x_common_api ) = { };
408
+ static DEVICE_API (gpio , gpio_siwx91x_common_api ) = {};
374
409
375
410
#define GPIO_CONTROLLER_INIT (idx ) \
376
411
static const struct gpio_siwx91x_common_config gpio_siwx91x_config##idx = { \
@@ -384,7 +419,8 @@ static DEVICE_API(gpio, gpio_siwx91x_common_api) = { };
384
419
int status; \
385
420
\
386
421
status = sl_si91x_gpio_driver_enable_clock( \
387
- COND_CODE_1(DT_INST_PROP(idx, silabs_ulp), (ULPCLK_GPIO), (M4CLK_GPIO))); \
422
+ COND_CODE_1(DT_INST_PROP(idx, silabs_ulp), (ULPCLK_GPIO), \
423
+ (M4CLK_GPIO))); \
388
424
if (status) { \
389
425
return -ENODEV; \
390
426
} \
@@ -395,8 +431,8 @@ static DEVICE_API(gpio, gpio_siwx91x_common_api) = { };
395
431
return 0; \
396
432
} \
397
433
DEVICE_DT_INST_DEFINE(idx, gpio_siwx91x_init_controller_##idx, NULL, \
398
- &gpio_siwx91x_data##idx, &gpio_siwx91x_config##idx, \
399
- PRE_KERNEL_1, CONFIG_GPIO_SILABS_SIWX91X_COMMON_INIT_PRIORITY, \
434
+ &gpio_siwx91x_data##idx, &gpio_siwx91x_config##idx, PRE_KERNEL_1, \
435
+ CONFIG_GPIO_SILABS_SIWX91X_COMMON_INIT_PRIORITY, \
400
436
&gpio_siwx91x_common_api); \
401
437
DT_INST_FOREACH_CHILD_STATUS_OKAY(idx, GPIO_PORT_INIT);
402
438
0 commit comments