Skip to content

Commit 6fc5bdf

Browse files
noglitchclaudiubeznea
authored andcommitted
ARM: at91: pm: change BU Power Switch to automatic mode
Change how the Backup Unit Power is configured and force the automatic/hardware mode. This change eliminates the need for software management of the power switch, ensuring it transitions to the backup power source before entering low power modes. This is done in the only location where this switch was configured. It's usually done in the bootloader. Previously, the loss of the VDDANA (or VDDIN33) power source was not automatically compensated by an alternative power source. This resulted in the loss of Backup Unit content, including Backup Self-refresh low power mode information, OTP emulation configuration, and boot configuration, for instance. Fixes: ac809e7 ("ARM: at91: pm: switch backup area to vbat in backup mode") Signed-off-by: Nicolas Ferre <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Claudiu Beznea <[email protected]>
1 parent d3455ab commit 6fc5bdf

File tree

1 file changed

+20
-11
lines changed
  • arch/arm/mach-at91

1 file changed

+20
-11
lines changed

arch/arm/mach-at91/pm.c

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,21 @@ static int at91_suspend_finish(unsigned long val)
598598
return 0;
599599
}
600600

601-
static void at91_pm_switch_ba_to_vbat(void)
601+
/**
602+
* at91_pm_switch_ba_to_auto() - Configure Backup Unit Power Switch
603+
* to automatic/hardware mode.
604+
*
605+
* The Backup Unit Power Switch can be managed either by software or hardware.
606+
* Enabling hardware mode allows the automatic transition of power between
607+
* VDDANA (or VDDIN33) and VDDBU (or VBAT, respectively), based on the
608+
* availability of these power sources.
609+
*
610+
* If the Backup Unit Power Switch is already in automatic mode, no action is
611+
* required. If it is in software-controlled mode, it is switched to automatic
612+
* mode to enhance safety and eliminate the need for toggling between power
613+
* sources.
614+
*/
615+
static void at91_pm_switch_ba_to_auto(void)
602616
{
603617
unsigned int offset = offsetof(struct at91_pm_sfrbu_regs, pswbu);
604618
unsigned int val;
@@ -609,24 +623,19 @@ static void at91_pm_switch_ba_to_vbat(void)
609623

610624
val = readl(soc_pm.data.sfrbu + offset);
611625

612-
/* Already on VBAT. */
613-
if (!(val & soc_pm.sfrbu_regs.pswbu.state))
626+
/* Already on auto/hardware. */
627+
if (!(val & soc_pm.sfrbu_regs.pswbu.ctrl))
614628
return;
615629

616-
val &= ~soc_pm.sfrbu_regs.pswbu.softsw;
617-
val |= soc_pm.sfrbu_regs.pswbu.key | soc_pm.sfrbu_regs.pswbu.ctrl;
630+
val &= ~soc_pm.sfrbu_regs.pswbu.ctrl;
631+
val |= soc_pm.sfrbu_regs.pswbu.key;
618632
writel(val, soc_pm.data.sfrbu + offset);
619-
620-
/* Wait for update. */
621-
val = readl(soc_pm.data.sfrbu + offset);
622-
while (val & soc_pm.sfrbu_regs.pswbu.state)
623-
val = readl(soc_pm.data.sfrbu + offset);
624633
}
625634

626635
static void at91_pm_suspend(suspend_state_t state)
627636
{
628637
if (soc_pm.data.mode == AT91_PM_BACKUP) {
629-
at91_pm_switch_ba_to_vbat();
638+
at91_pm_switch_ba_to_auto();
630639

631640
cpu_suspend(0, at91_suspend_finish);
632641

0 commit comments

Comments
 (0)