[PATCH] ARM: stm32: Ping IWDG on exit from PSCI suspend code

Make sure the OS would not get any spurious IWDG pretimeout IRQ right after the system wakes up. This may happen in case the SoC got woken up by another source than the IWDG pretimeout and the pretimeout IRQ arrived immediately afterward, but too late to be handled by the suspend main loop. In case either of the IWDG is enabled, ping it first and then return to the OS.
Signed-off-by: Marek Vasut marex@denx.de --- Cc: Igor Opaniuk igor.opaniuk@foundries.io Cc: Patrice Chotard patrice.chotard@foss.st.com Cc: Patrick Delaunay patrick.delaunay@foss.st.com Cc: Simon Glass sjg@chromium.org Cc: Tom Rini trini@konsulko.com Cc: u-boot@dh-electronics.com Cc: uboot-stm32@st-md-mailman.stormreply.com --- arch/arm/mach-stm32mp/stm32mp1/psci.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
diff --git a/arch/arm/mach-stm32mp/stm32mp1/psci.c b/arch/arm/mach-stm32mp/stm32mp1/psci.c index 4f2379df45f..e99103910d9 100644 --- a/arch/arm/mach-stm32mp/stm32mp1/psci.c +++ b/arch/arm/mach-stm32mp/stm32mp1/psci.c @@ -808,6 +808,27 @@ void __secure psci_system_suspend(u32 __always_unused function_id, writel(SYSCFG_CMPENR_MPUEN, STM32_SYSCFG_BASE + SYSCFG_CMPENSETR); clrbits_le32(STM32_SYSCFG_BASE + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL);
+ /* + * Make sure the OS would not get any spurious IWDG pretimeout IRQ + * right after the system wakes up. This may happen in case the SoC + * got woken up by another source than the IWDG pretimeout and the + * pretimeout IRQ arrived immediately afterward, but too late to be + * handled by the main loop above. In case either of the IWDG is + * enabled, ping it first and then return to the OS. + */ + + /* Ping IWDG1 and ACK pretimer IRQ */ + if (gic_enabled[4] & BIT(22)) { + writel(IWDG_KR_RELOAD_KEY, STM32_IWDG1_BASE + IWDG_KR); + writel(IWDG_EWCR_EWIC, STM32_IWDG1_BASE + IWDG_EWCR); + } + + /* Ping IWDG2 and ACK pretimer IRQ */ + if (gic_enabled[4] & BIT(23)) { + writel(IWDG_KR_RELOAD_KEY, STM32_IWDG2_BASE + IWDG_KR); + writel(IWDG_EWCR_EWIC, STM32_IWDG2_BASE + IWDG_EWCR); + } + /* * The system has resumed successfully. Rewrite LR register stored * on stack with 'ep' value, so that on return from this PSCI call,

On 4/20/24 00:03, Marek Vasut wrote:
Make sure the OS would not get any spurious IWDG pretimeout IRQ right after the system wakes up. This may happen in case the SoC got woken up by another source than the IWDG pretimeout and the pretimeout IRQ arrived immediately afterward, but too late to be handled by the suspend main loop. In case either of the IWDG is enabled, ping it first and then return to the OS.
Signed-off-by: Marek Vasut marex@denx.de
Cc: Igor Opaniuk igor.opaniuk@foundries.io Cc: Patrice Chotard patrice.chotard@foss.st.com Cc: Patrick Delaunay patrick.delaunay@foss.st.com Cc: Simon Glass sjg@chromium.org Cc: Tom Rini trini@konsulko.com Cc: u-boot@dh-electronics.com Cc: uboot-stm32@st-md-mailman.stormreply.com
arch/arm/mach-stm32mp/stm32mp1/psci.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
diff --git a/arch/arm/mach-stm32mp/stm32mp1/psci.c b/arch/arm/mach-stm32mp/stm32mp1/psci.c index 4f2379df45f..e99103910d9 100644 --- a/arch/arm/mach-stm32mp/stm32mp1/psci.c +++ b/arch/arm/mach-stm32mp/stm32mp1/psci.c @@ -808,6 +808,27 @@ void __secure psci_system_suspend(u32 __always_unused function_id, writel(SYSCFG_CMPENR_MPUEN, STM32_SYSCFG_BASE + SYSCFG_CMPENSETR); clrbits_le32(STM32_SYSCFG_BASE + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL);
- /*
* Make sure the OS would not get any spurious IWDG pretimeout IRQ
* right after the system wakes up. This may happen in case the SoC
* got woken up by another source than the IWDG pretimeout and the
* pretimeout IRQ arrived immediately afterward, but too late to be
* handled by the main loop above. In case either of the IWDG is
* enabled, ping it first and then return to the OS.
*/
- /* Ping IWDG1 and ACK pretimer IRQ */
- if (gic_enabled[4] & BIT(22)) {
writel(IWDG_KR_RELOAD_KEY, STM32_IWDG1_BASE + IWDG_KR);
writel(IWDG_EWCR_EWIC, STM32_IWDG1_BASE + IWDG_EWCR);
- }
- /* Ping IWDG2 and ACK pretimer IRQ */
- if (gic_enabled[4] & BIT(23)) {
writel(IWDG_KR_RELOAD_KEY, STM32_IWDG2_BASE + IWDG_KR);
writel(IWDG_EWCR_EWIC, STM32_IWDG2_BASE + IWDG_EWCR);
- }
- /*
- The system has resumed successfully. Rewrite LR register stored
- on stack with 'ep' value, so that on return from this PSCI call,
Reviewed-by: Patrice Chotard patrice.chotard@foss.st.com
Thanks Patrice

On Sat, Apr 20, 2024 at 12:03 AM Marek Vasut marex@denx.de wrote:
Make sure the OS would not get any spurious IWDG pretimeout IRQ right after the system wakes up. This may happen in case the SoC got woken up by another source than the IWDG pretimeout and the pretimeout IRQ arrived immediately afterward, but too late to be handled by the suspend main loop. In case either of the IWDG is enabled, ping it first and then return to the OS.
Signed-off-by: Marek Vasut marex@denx.de
Cc: Igor Opaniuk igor.opaniuk@foundries.io Cc: Patrice Chotard patrice.chotard@foss.st.com Cc: Patrick Delaunay patrick.delaunay@foss.st.com Cc: Simon Glass sjg@chromium.org Cc: Tom Rini trini@konsulko.com Cc: u-boot@dh-electronics.com Cc: uboot-stm32@st-md-mailman.stormreply.com
arch/arm/mach-stm32mp/stm32mp1/psci.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
diff --git a/arch/arm/mach-stm32mp/stm32mp1/psci.c b/arch/arm/mach-stm32mp/stm32mp1/psci.c index 4f2379df45f..e99103910d9 100644 --- a/arch/arm/mach-stm32mp/stm32mp1/psci.c +++ b/arch/arm/mach-stm32mp/stm32mp1/psci.c @@ -808,6 +808,27 @@ void __secure psci_system_suspend(u32 __always_unused function_id, writel(SYSCFG_CMPENR_MPUEN, STM32_SYSCFG_BASE + SYSCFG_CMPENSETR); clrbits_le32(STM32_SYSCFG_BASE + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL);
/*
* Make sure the OS would not get any spurious IWDG pretimeout IRQ
* right after the system wakes up. This may happen in case the SoC
* got woken up by another source than the IWDG pretimeout and the
* pretimeout IRQ arrived immediately afterward, but too late to be
* handled by the main loop above. In case either of the IWDG is
* enabled, ping it first and then return to the OS.
*/
/* Ping IWDG1 and ACK pretimer IRQ */
if (gic_enabled[4] & BIT(22)) {
writel(IWDG_KR_RELOAD_KEY, STM32_IWDG1_BASE + IWDG_KR);
writel(IWDG_EWCR_EWIC, STM32_IWDG1_BASE + IWDG_EWCR);
}
/* Ping IWDG2 and ACK pretimer IRQ */
if (gic_enabled[4] & BIT(23)) {
writel(IWDG_KR_RELOAD_KEY, STM32_IWDG2_BASE + IWDG_KR);
writel(IWDG_EWCR_EWIC, STM32_IWDG2_BASE + IWDG_EWCR);
}
/* * The system has resumed successfully. Rewrite LR register stored * on stack with 'ep' value, so that on return from this PSCI call,
-- 2.43.0
Reviewed-by: Igor Opaniuk igor.opaniuk@foundries.io

On 6/10/24 10:36, Igor Opaniuk wrote:
On Sat, Apr 20, 2024 at 12:03 AM Marek Vasut marex@denx.de wrote:
Make sure the OS would not get any spurious IWDG pretimeout IRQ right after the system wakes up. This may happen in case the SoC got woken up by another source than the IWDG pretimeout and the pretimeout IRQ arrived immediately afterward, but too late to be handled by the suspend main loop. In case either of the IWDG is enabled, ping it first and then return to the OS.
Signed-off-by: Marek Vasut marex@denx.de
Cc: Igor Opaniuk igor.opaniuk@foundries.io Cc: Patrice Chotard patrice.chotard@foss.st.com Cc: Patrick Delaunay patrick.delaunay@foss.st.com Cc: Simon Glass sjg@chromium.org Cc: Tom Rini trini@konsulko.com Cc: u-boot@dh-electronics.com Cc: uboot-stm32@st-md-mailman.stormreply.com
arch/arm/mach-stm32mp/stm32mp1/psci.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
diff --git a/arch/arm/mach-stm32mp/stm32mp1/psci.c b/arch/arm/mach-stm32mp/stm32mp1/psci.c index 4f2379df45f..e99103910d9 100644 --- a/arch/arm/mach-stm32mp/stm32mp1/psci.c +++ b/arch/arm/mach-stm32mp/stm32mp1/psci.c @@ -808,6 +808,27 @@ void __secure psci_system_suspend(u32 __always_unused function_id, writel(SYSCFG_CMPENR_MPUEN, STM32_SYSCFG_BASE + SYSCFG_CMPENSETR); clrbits_le32(STM32_SYSCFG_BASE + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL);
/*
* Make sure the OS would not get any spurious IWDG pretimeout IRQ
* right after the system wakes up. This may happen in case the SoC
* got woken up by another source than the IWDG pretimeout and the
* pretimeout IRQ arrived immediately afterward, but too late to be
* handled by the main loop above. In case either of the IWDG is
* enabled, ping it first and then return to the OS.
*/
/* Ping IWDG1 and ACK pretimer IRQ */
if (gic_enabled[4] & BIT(22)) {
writel(IWDG_KR_RELOAD_KEY, STM32_IWDG1_BASE + IWDG_KR);
writel(IWDG_EWCR_EWIC, STM32_IWDG1_BASE + IWDG_EWCR);
}
/* Ping IWDG2 and ACK pretimer IRQ */
if (gic_enabled[4] & BIT(23)) {
writel(IWDG_KR_RELOAD_KEY, STM32_IWDG2_BASE + IWDG_KR);
writel(IWDG_EWCR_EWIC, STM32_IWDG2_BASE + IWDG_EWCR);
}
/* * The system has resumed successfully. Rewrite LR register stored * on stack with 'ep' value, so that on return from this PSCI call,
-- 2.43.0
Reviewed-by: Igor Opaniuk igor.opaniuk@foundries.io
Applied to u-boot-stm32/next
Thanks Patrice

On 4/20/24 00:03, Marek Vasut wrote:
Make sure the OS would not get any spurious IWDG pretimeout IRQ right after the system wakes up. This may happen in case the SoC got woken up by another source than the IWDG pretimeout and the pretimeout IRQ arrived immediately afterward, but too late to be handled by the suspend main loop. In case either of the IWDG is enabled, ping it first and then return to the OS.
Signed-off-by: Marek Vasut marex@denx.de
Cc: Igor Opaniuk igor.opaniuk@foundries.io Cc: Patrice Chotard patrice.chotard@foss.st.com Cc: Patrick Delaunay patrick.delaunay@foss.st.com Cc: Simon Glass sjg@chromium.org Cc: Tom Rini trini@konsulko.com Cc: u-boot@dh-electronics.com Cc: uboot-stm32@st-md-mailman.stormreply.com
arch/arm/mach-stm32mp/stm32mp1/psci.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
diff --git a/arch/arm/mach-stm32mp/stm32mp1/psci.c b/arch/arm/mach-stm32mp/stm32mp1/psci.c index 4f2379df45f..e99103910d9 100644 --- a/arch/arm/mach-stm32mp/stm32mp1/psci.c +++ b/arch/arm/mach-stm32mp/stm32mp1/psci.c @@ -808,6 +808,27 @@ void __secure psci_system_suspend(u32 __always_unused function_id, writel(SYSCFG_CMPENR_MPUEN, STM32_SYSCFG_BASE + SYSCFG_CMPENSETR); clrbits_le32(STM32_SYSCFG_BASE + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL);
- /*
* Make sure the OS would not get any spurious IWDG pretimeout IRQ
* right after the system wakes up. This may happen in case the SoC
* got woken up by another source than the IWDG pretimeout and the
* pretimeout IRQ arrived immediately afterward, but too late to be
* handled by the main loop above. In case either of the IWDG is
* enabled, ping it first and then return to the OS.
*/
- /* Ping IWDG1 and ACK pretimer IRQ */
- if (gic_enabled[4] & BIT(22)) {
writel(IWDG_KR_RELOAD_KEY, STM32_IWDG1_BASE + IWDG_KR);
writel(IWDG_EWCR_EWIC, STM32_IWDG1_BASE + IWDG_EWCR);
- }
- /* Ping IWDG2 and ACK pretimer IRQ */
- if (gic_enabled[4] & BIT(23)) {
writel(IWDG_KR_RELOAD_KEY, STM32_IWDG2_BASE + IWDG_KR);
writel(IWDG_EWCR_EWIC, STM32_IWDG2_BASE + IWDG_EWCR);
- }
- /*
- The system has resumed successfully. Rewrite LR register stored
- on stack with 'ep' value, so that on return from this PSCI call,
Applied to u-boot-stm32/next
Thanks Patrice

On 6/14/24 2:00 PM, Patrice CHOTARD wrote:
On 4/20/24 00:03, Marek Vasut wrote:
Make sure the OS would not get any spurious IWDG pretimeout IRQ right after the system wakes up. This may happen in case the SoC got woken up by another source than the IWDG pretimeout and the pretimeout IRQ arrived immediately afterward, but too late to be handled by the suspend main loop. In case either of the IWDG is enabled, ping it first and then return to the OS.
Signed-off-by: Marek Vasut marex@denx.de
Cc: Igor Opaniuk igor.opaniuk@foundries.io Cc: Patrice Chotard patrice.chotard@foss.st.com Cc: Patrick Delaunay patrick.delaunay@foss.st.com Cc: Simon Glass sjg@chromium.org Cc: Tom Rini trini@konsulko.com Cc: u-boot@dh-electronics.com Cc: uboot-stm32@st-md-mailman.stormreply.com
arch/arm/mach-stm32mp/stm32mp1/psci.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
diff --git a/arch/arm/mach-stm32mp/stm32mp1/psci.c b/arch/arm/mach-stm32mp/stm32mp1/psci.c index 4f2379df45f..e99103910d9 100644 --- a/arch/arm/mach-stm32mp/stm32mp1/psci.c +++ b/arch/arm/mach-stm32mp/stm32mp1/psci.c @@ -808,6 +808,27 @@ void __secure psci_system_suspend(u32 __always_unused function_id, writel(SYSCFG_CMPENR_MPUEN, STM32_SYSCFG_BASE + SYSCFG_CMPENSETR); clrbits_le32(STM32_SYSCFG_BASE + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL);
- /*
* Make sure the OS would not get any spurious IWDG pretimeout IRQ
* right after the system wakes up. This may happen in case the SoC
* got woken up by another source than the IWDG pretimeout and the
* pretimeout IRQ arrived immediately afterward, but too late to be
* handled by the main loop above. In case either of the IWDG is
* enabled, ping it first and then return to the OS.
*/
- /* Ping IWDG1 and ACK pretimer IRQ */
- if (gic_enabled[4] & BIT(22)) {
writel(IWDG_KR_RELOAD_KEY, STM32_IWDG1_BASE + IWDG_KR);
writel(IWDG_EWCR_EWIC, STM32_IWDG1_BASE + IWDG_EWCR);
- }
- /* Ping IWDG2 and ACK pretimer IRQ */
- if (gic_enabled[4] & BIT(23)) {
writel(IWDG_KR_RELOAD_KEY, STM32_IWDG2_BASE + IWDG_KR);
writel(IWDG_EWCR_EWIC, STM32_IWDG2_BASE + IWDG_EWCR);
- }
- /*
- The system has resumed successfully. Rewrite LR register stored
- on stack with 'ep' value, so that on return from this PSCI call,
Applied to u-boot-stm32/next
This is a fix, should go into /master .

On 6/14/24 15:06, Marek Vasut wrote:
On 6/14/24 2:00 PM, Patrice CHOTARD wrote:
On 4/20/24 00:03, Marek Vasut wrote:
Make sure the OS would not get any spurious IWDG pretimeout IRQ right after the system wakes up. This may happen in case the SoC got woken up by another source than the IWDG pretimeout and the pretimeout IRQ arrived immediately afterward, but too late to be handled by the suspend main loop. In case either of the IWDG is enabled, ping it first and then return to the OS.
Signed-off-by: Marek Vasut marex@denx.de
Cc: Igor Opaniuk igor.opaniuk@foundries.io Cc: Patrice Chotard patrice.chotard@foss.st.com Cc: Patrick Delaunay patrick.delaunay@foss.st.com Cc: Simon Glass sjg@chromium.org Cc: Tom Rini trini@konsulko.com Cc: u-boot@dh-electronics.com Cc: uboot-stm32@st-md-mailman.stormreply.com
arch/arm/mach-stm32mp/stm32mp1/psci.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
diff --git a/arch/arm/mach-stm32mp/stm32mp1/psci.c b/arch/arm/mach-stm32mp/stm32mp1/psci.c index 4f2379df45f..e99103910d9 100644 --- a/arch/arm/mach-stm32mp/stm32mp1/psci.c +++ b/arch/arm/mach-stm32mp/stm32mp1/psci.c @@ -808,6 +808,27 @@ void __secure psci_system_suspend(u32 __always_unused function_id, writel(SYSCFG_CMPENR_MPUEN, STM32_SYSCFG_BASE + SYSCFG_CMPENSETR); clrbits_le32(STM32_SYSCFG_BASE + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL); + /* + * Make sure the OS would not get any spurious IWDG pretimeout IRQ + * right after the system wakes up. This may happen in case the SoC + * got woken up by another source than the IWDG pretimeout and the + * pretimeout IRQ arrived immediately afterward, but too late to be + * handled by the main loop above. In case either of the IWDG is + * enabled, ping it first and then return to the OS. + */
+ /* Ping IWDG1 and ACK pretimer IRQ */ + if (gic_enabled[4] & BIT(22)) { + writel(IWDG_KR_RELOAD_KEY, STM32_IWDG1_BASE + IWDG_KR); + writel(IWDG_EWCR_EWIC, STM32_IWDG1_BASE + IWDG_EWCR); + }
+ /* Ping IWDG2 and ACK pretimer IRQ */ + if (gic_enabled[4] & BIT(23)) { + writel(IWDG_KR_RELOAD_KEY, STM32_IWDG2_BASE + IWDG_KR); + writel(IWDG_EWCR_EWIC, STM32_IWDG2_BASE + IWDG_EWCR); + }
/* * The system has resumed successfully. Rewrite LR register stored * on stack with 'ep' value, so that on return from this PSCI call,
Applied to u-boot-stm32/next
This is a fix, should go into /master .
Ah yes :-( , i will send another PR for fixes on monday
Thanks for pointing this
PAtrice

On 6/14/24 4:02 PM, Patrice CHOTARD wrote:
On 6/14/24 15:06, Marek Vasut wrote:
On 6/14/24 2:00 PM, Patrice CHOTARD wrote:
On 4/20/24 00:03, Marek Vasut wrote:
Make sure the OS would not get any spurious IWDG pretimeout IRQ right after the system wakes up. This may happen in case the SoC got woken up by another source than the IWDG pretimeout and the pretimeout IRQ arrived immediately afterward, but too late to be handled by the suspend main loop. In case either of the IWDG is enabled, ping it first and then return to the OS.
Signed-off-by: Marek Vasut marex@denx.de
Cc: Igor Opaniuk igor.opaniuk@foundries.io Cc: Patrice Chotard patrice.chotard@foss.st.com Cc: Patrick Delaunay patrick.delaunay@foss.st.com Cc: Simon Glass sjg@chromium.org Cc: Tom Rini trini@konsulko.com Cc: u-boot@dh-electronics.com Cc: uboot-stm32@st-md-mailman.stormreply.com
arch/arm/mach-stm32mp/stm32mp1/psci.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
diff --git a/arch/arm/mach-stm32mp/stm32mp1/psci.c b/arch/arm/mach-stm32mp/stm32mp1/psci.c index 4f2379df45f..e99103910d9 100644 --- a/arch/arm/mach-stm32mp/stm32mp1/psci.c +++ b/arch/arm/mach-stm32mp/stm32mp1/psci.c @@ -808,6 +808,27 @@ void __secure psci_system_suspend(u32 __always_unused function_id, writel(SYSCFG_CMPENR_MPUEN, STM32_SYSCFG_BASE + SYSCFG_CMPENSETR); clrbits_le32(STM32_SYSCFG_BASE + SYSCFG_CMPCR, SYSCFG_CMPCR_SW_CTRL); + /* + * Make sure the OS would not get any spurious IWDG pretimeout IRQ + * right after the system wakes up. This may happen in case the SoC + * got woken up by another source than the IWDG pretimeout and the + * pretimeout IRQ arrived immediately afterward, but too late to be + * handled by the main loop above. In case either of the IWDG is + * enabled, ping it first and then return to the OS. + */
+ /* Ping IWDG1 and ACK pretimer IRQ */ + if (gic_enabled[4] & BIT(22)) { + writel(IWDG_KR_RELOAD_KEY, STM32_IWDG1_BASE + IWDG_KR); + writel(IWDG_EWCR_EWIC, STM32_IWDG1_BASE + IWDG_EWCR); + }
+ /* Ping IWDG2 and ACK pretimer IRQ */ + if (gic_enabled[4] & BIT(23)) { + writel(IWDG_KR_RELOAD_KEY, STM32_IWDG2_BASE + IWDG_KR); + writel(IWDG_EWCR_EWIC, STM32_IWDG2_BASE + IWDG_EWCR); + }
/* * The system has resumed successfully. Rewrite LR register stored * on stack with 'ep' value, so that on return from this PSCI call,
Applied to u-boot-stm32/next
This is a fix, should go into /master .
Ah yes :-( , i will send another PR for fixes on monday
Thank you !
participants (3)
-
Igor Opaniuk
-
Marek Vasut
-
Patrice CHOTARD