Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions drivers/gpio/gpio_rts5912.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
#include "zephyr/drivers/gpio/gpio_utils.h"
#include <zephyr/logging/log.h>
#include <zephyr/dt-bindings/gpio/realtek-gpio.h>
#include <zephyr/pm/pm.h>
#include <zephyr/pm/policy.h>
#include <zephyr/sys/atomic.h>

#include <reg/reg_gpio.h>

Expand All @@ -33,6 +36,22 @@ struct gpio_rts5912_data {
sys_slist_t callbacks;
};

#if defined(CONFIG_PM)
#define GPIO_EXPIRED_TIMEOUT_MS 1000
static struct k_work_delayable gpio_wake_delay_work;
static atomic_t gpio_wake_hold; /* 0: no hold, 1: holding */
static atomic_t gpio_wake_init_once; /* 0: not inited, 1: inited */

static void gpio_wake_delay_work_handler(struct k_work *work)
{
ARG_UNUSED(work);

if (atomic_cas(&gpio_wake_hold, 1, 0)) {
pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES);
}
}
#endif /* CONFIG_PM */

static int pin_is_valid(const struct gpio_rts5912_config *config, gpio_pin_t pin)
{
if (pin >= config->num_pins) {
Expand Down Expand Up @@ -455,6 +474,14 @@ static void gpio_rts5912_isr(const void *arg)
if (gcr[pin] & GPIO_GCR_INTSTS_Msk) {
gcr[pin] |= GPIO_GCR_INTSTS_Msk;

#if defined(CONFIG_PM)
if (atomic_cas(&gpio_wake_hold, 0, 1)) {
pm_policy_state_lock_get(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES);
}
k_work_reschedule(&gpio_wake_delay_work,
K_MSEC(GPIO_EXPIRED_TIMEOUT_MS));
#endif

gpio_fire_callbacks(&data->callbacks, port, BIT(pin));
}
irq_unlock(key);
Expand Down Expand Up @@ -567,6 +594,14 @@ static DEVICE_API(gpio, gpio_rts5912_driver_api) = {
{ \
if (!(DT_INST_IRQ_HAS_CELL(id, irq))) { \
return 0; \
} \
\
if (IS_ENABLED(CONFIG_PM)) { \
if (atomic_cas(&gpio_wake_init_once, 0, 1)) { \
k_work_init_delayable(&gpio_wake_delay_work, \
gpio_wake_delay_work_handler); \
atomic_clear(&gpio_wake_hold); \
} \
} \
\
RTS5912_GPIO_DTNAMIC_IRQ(id) \
Expand Down