From: Heiko Stuebner <heiko@sntech.de>
To: Linus Walleij <linusw@kernel.org>,
Bartosz Golaszewski <brgl@kernel.org>,
iav@iav.lv
Cc: Jianqun Xu <jay.xu@rock-chips.com>,
linux-gpio@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-rockchip@lists.infradead.org, linux-kernel@vger.kernel.org,
Igor Velkov <iav@iav.lv>,
stable@vger.kernel.org
Subject: Re: [PATCH] gpio: rockchip: restore interrupt settings after hibernation
Date: Sat, 07 Nov 2026 15:38:38 +0100 [thread overview]
Message-ID: <9970336.2WqB4rESCP@phil> (raw)
In-Reply-To: <20261107-b4-gpio-rockchip-hib-v1-1-19f4d163a55e@iav.lv>
Am Samstag, 7. November 2026, 06:55:00 Mitteleuropäische Normalzeit schrieb Igor Velkov via B4 Relay:
> From: Igor Velkov <iav@iav.lv>
>
> Restore from hibernation follows a cold boot. The boot kernel probes
> the GPIO banks, sets every interrupt enable bit, leaves the trigger of
> each line it did not request at the reset value, and then hands over
> to the image. The image restores only the interrupt masks, so a line
> it had set up for both edges comes back with the reset trigger.
>
> On ODROID-M1 the headphone detect line (GPIO0_B0) is requested for
> both edges and is low with nothing plugged in. After a power loss in
> hybrid sleep its reset trigger fires again as soon as the edge handler
> acknowledges it, and the system does not come back. With this patch
> the board resumed 4 of 4 times, without it 0 of 5.
>
> Save the interrupt enable, type, polarity and both-edge registers with
> the masks and write them back before unmasking. In a normal suspend
> the bank keeps its registers, so this writes back what is already
> there. For lines that emulate both edges on GPIO v1, take the polarity
> from the current pin level.
>
> Fixes: 936ee2675eee ("gpio/rockchip: add driver for rockchip gpio")
> Cc: stable@vger.kernel.org
> Signed-off-by: Igor Velkov <iav@iav.lv>
This looks sensible in general, but I wonder what happens with the other
registers of the gpio-controller here after hibernation?
Like does the direction + output value, debounce get restored from
some other means?
Heiko
> ---
> Tested on ODROID-M1 (RK3568, GPIO v2): hybrid sleep with power removed
> during sleep 4/4, deep sleep 10/10. The GPIO v1 path was not tested on
> hardware.
> ---
> drivers/gpio/gpio-rockchip.c | 21 +++++++++++++++++++++
> drivers/pinctrl/pinctrl-rockchip.h | 8 ++++++++
> 2 files changed, 29 insertions(+)
>
> diff --git a/drivers/gpio/gpio-rockchip.c b/drivers/gpio/gpio-rockchip.c
> index 0f46ff095a24..83a5cc8f3fe6 100644
> --- a/drivers/gpio/gpio-rockchip.c
> +++ b/drivers/gpio/gpio-rockchip.c
> @@ -489,6 +489,11 @@ static void rockchip_irq_suspend(struct irq_data *d)
> struct rockchip_pin_bank *bank = gc->private;
>
> bank->saved_masks = irq_reg_readl(gc, bank->gpio_regs->int_mask);
> + bank->saved_en = rockchip_gpio_readl(bank, bank->gpio_regs->int_en);
> + bank->saved_type = rockchip_gpio_readl(bank, bank->gpio_regs->int_type);
> + bank->saved_polarity = rockchip_gpio_readl(bank, bank->gpio_regs->int_polarity);
> + if (bank->gpio_type == GPIO_TYPE_V2)
> + bank->saved_bothedge = rockchip_gpio_readl(bank, bank->gpio_regs->int_bothedge);
> irq_reg_writel(gc, ~gc->wake_active, bank->gpio_regs->int_mask);
> }
>
> @@ -496,7 +501,23 @@ static void rockchip_irq_resume(struct irq_data *d)
> {
> struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
> struct rockchip_pin_bank *bank = gc->private;
> + u32 polarity = bank->saved_polarity;
> +
> + /*
> + * Restore from hibernation follows a cold boot: write the enables and
> + * the trigger back before we unmask.
> + */
> + if (bank->toggle_edge_mode) {
> + u32 data = readl(bank->reg_base + bank->gpio_regs->ext_port);
>
> + polarity &= ~bank->toggle_edge_mode;
> + polarity |= ~data & bank->toggle_edge_mode;
> + }
> + rockchip_gpio_writel(bank, bank->saved_en, bank->gpio_regs->int_en);
> + rockchip_gpio_writel(bank, bank->saved_type, bank->gpio_regs->int_type);
> + rockchip_gpio_writel(bank, polarity, bank->gpio_regs->int_polarity);
> + if (bank->gpio_type == GPIO_TYPE_V2)
> + rockchip_gpio_writel(bank, bank->saved_bothedge, bank->gpio_regs->int_bothedge);
> irq_reg_writel(gc, bank->saved_masks, bank->gpio_regs->int_mask);
> }
>
> diff --git a/drivers/pinctrl/pinctrl-rockchip.h b/drivers/pinctrl/pinctrl-rockchip.h
> index 950097699643..ea280843fcb9 100644
> --- a/drivers/pinctrl/pinctrl-rockchip.h
> +++ b/drivers/pinctrl/pinctrl-rockchip.h
> @@ -303,6 +303,10 @@ struct rockchip_drv {
> * @db_clk: clock of the gpio debounce
> * @irq: interrupt of the gpio bank
> * @saved_masks: Saved content of GPIO_INTEN at suspend time.
> + * @saved_en: interrupt enables, saved at suspend time.
> + * @saved_type: interrupt level/edge type, saved at suspend time.
> + * @saved_polarity: interrupt polarity, saved at suspend time.
> + * @saved_bothedge: interrupt both-edge enables (GPIO v2), saved at suspend time.
> * @pin_base: first pin number
> * @nr_pins: number of pins in this bank
> * @name: name of the bank
> @@ -332,6 +336,10 @@ struct rockchip_pin_bank {
> struct clk *db_clk;
> int irq;
> u32 saved_masks;
> + u32 saved_en;
> + u32 saved_type;
> + u32 saved_polarity;
> + u32 saved_bothedge;
> u32 pin_base;
> u8 nr_pins;
> char *name;
>
> ---
> base-commit: 0fa38ba784896f2fc32c9dacd33822f844b21906
> change-id: 20261107-b4-gpio-rockchip-hib-705c3fd52b49
>
> Best regards,
>
prev parent reply other threads:[~2026-11-07 14:38 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-07 5:55 Igor Velkov via B4 Relay
2026-11-07 14:38 ` Heiko Stuebner [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=9970336.2WqB4rESCP@phil \
--to=heiko@sntech.de \
--cc=brgl@kernel.org \
--cc=iav@iav.lv \
--cc=jay.xu@rock-chips.com \
--cc=linusw@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rockchip@lists.infradead.org \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®