|
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,9 +58,42 @@ 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 | +#if defined(CONFIG_PM) |
| 62 | + /* stores the direction of each pin */ |
| 63 | + uint16_t pin_direction[MAX_PIN_COUNT]; |
| 64 | +#endif |
59 | 65 | };
|
60 | 66 |
|
61 | 67 | /* Functions */
|
| 68 | +static int gpio_siwx91x_port_pm_action(const struct device *port, enum pm_device_action action) |
| 69 | +{ |
| 70 | + __maybe_unused const struct gpio_siwx91x_port_config *config = port->config; |
| 71 | + __maybe_unused struct gpio_siwx91x_port_data *data = port->data; |
| 72 | +#if defined(CONFIG_PM) |
| 73 | + switch (action) { |
| 74 | + case PM_DEVICE_ACTION_RESUME: |
| 75 | + for (int pin = 0; pin < MAX_PIN_COUNT; ++pin) { |
| 76 | + if (config->common.port_pin_mask & BIT(pin)) { |
| 77 | + sl_si91x_gpio_set_pin_direction(config->hal_port, pin, |
| 78 | + data->pin_direction[pin]); |
| 79 | + } |
| 80 | + } |
| 81 | + break; |
| 82 | + case PM_DEVICE_ACTION_SUSPEND: |
| 83 | + for (int pin = 0; pin < MAX_PIN_COUNT; ++pin) { |
| 84 | + if (config->common.port_pin_mask & BIT(pin)) { |
| 85 | + data->pin_direction[pin] = |
| 86 | + sl_si91x_gpio_get_pin_direction(config->hal_port, pin); |
| 87 | + } |
| 88 | + } |
| 89 | + break; |
| 90 | + default: |
| 91 | + return -ENOTSUP; |
| 92 | + } |
| 93 | +#endif |
| 94 | + return 0; |
| 95 | +} |
| 96 | + |
62 | 97 | static int gpio_siwx91x_pin_configure(const struct device *dev, gpio_pin_t pin, gpio_flags_t flags)
|
63 | 98 | {
|
64 | 99 | const struct gpio_siwx91x_port_config *cfg = dev->config;
|
@@ -295,7 +330,7 @@ static inline int gpio_siwx91x_init_port(const struct device *port)
|
295 | 330 | __ASSERT(cfg->port < MAX_PORT_COUNT, "Too many ports");
|
296 | 331 | data->ports[cfg->port] = port;
|
297 | 332 |
|
298 |
| - return 0; |
| 333 | + return pm_device_driver_init(port, gpio_siwx91x_port_pm_action); |
299 | 334 | }
|
300 | 335 |
|
301 | 336 | static void gpio_siwx91x_isr(const struct device *parent)
|
@@ -361,9 +396,10 @@ static DEVICE_API(gpio, gpio_siwx91x_api) = {
|
361 | 396 | }; \
|
362 | 397 | static struct gpio_siwx91x_port_data gpio_siwx91x_port_data##n; \
|
363 | 398 | \
|
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); |
| 399 | + PM_DEVICE_DT_INST_DEFINE(n, gpio_siwx91x_port_pm_action); \ |
| 400 | + DEVICE_DT_DEFINE(n, gpio_siwx91x_init_port, PM_DEVICE_DT_INST_GET(n), \ |
| 401 | + &gpio_siwx91x_port_data##n, &gpio_siwx91x_port_config##n, PRE_KERNEL_1, \ |
| 402 | + CONFIG_GPIO_INIT_PRIORITY, &gpio_siwx91x_api); |
367 | 403 |
|
368 | 404 | #define CONFIGURE_SHARED_INTERRUPT(node_id, prop, idx) \
|
369 | 405 | IRQ_CONNECT(DT_IRQ_BY_IDX(node_id, idx, irq), DT_IRQ_BY_IDX(node_id, idx, priority), \
|
|
0 commit comments