Skip to content

Commit 39add36

Browse files
claudiubezneaalexandrebelloni
authored andcommitted
ARM: at91: pm: add per soc validation of pm modes
Not all SoCs supports all the PM mode. User may end up settings, e.g. backup mode, on a non SAMA5D2 device, but the mode to not be valid. If backup mode is used on a devices not supporting it there will be no way of resuming other than rebooting. Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com> Link: https://lore.kernel.org/r/1596616610-15460-3-git-send-email-claudiu.beznea@microchip.com
1 parent e70bfc2 commit 39add36

1 file changed

Lines changed: 79 additions & 1 deletion

File tree

  • arch/arm/mach-at91

arch/arm/mach-at91/pm.c

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -790,6 +790,51 @@ static const struct of_device_id atmel_pmc_ids[] __initconst = {
790790
{ /* sentinel */ },
791791
};
792792

793+
static void __init at91_pm_modes_validate(const int *modes, int len)
794+
{
795+
u8 i, standby = 0, suspend = 0;
796+
int mode;
797+
798+
for (i = 0; i < len; i++) {
799+
if (standby && suspend)
800+
break;
801+
802+
if (modes[i] == soc_pm.data.standby_mode && !standby) {
803+
standby = 1;
804+
continue;
805+
}
806+
807+
if (modes[i] == soc_pm.data.suspend_mode && !suspend) {
808+
suspend = 1;
809+
continue;
810+
}
811+
}
812+
813+
if (!standby) {
814+
if (soc_pm.data.suspend_mode == AT91_PM_STANDBY)
815+
mode = AT91_PM_ULP0;
816+
else
817+
mode = AT91_PM_STANDBY;
818+
819+
pr_warn("AT91: PM: %s mode not supported! Using %s.\n",
820+
pm_modes[soc_pm.data.standby_mode].pattern,
821+
pm_modes[mode].pattern);
822+
soc_pm.data.standby_mode = mode;
823+
}
824+
825+
if (!suspend) {
826+
if (soc_pm.data.standby_mode == AT91_PM_ULP0)
827+
mode = AT91_PM_STANDBY;
828+
else
829+
mode = AT91_PM_ULP0;
830+
831+
pr_warn("AT91: PM: %s mode not supported! Using %s.\n",
832+
pm_modes[soc_pm.data.suspend_mode].pattern,
833+
pm_modes[mode].pattern);
834+
soc_pm.data.suspend_mode = mode;
835+
}
836+
}
837+
793838
static void __init at91_pm_init(void (*pm_idle)(void))
794839
{
795840
struct device_node *pmc_np;
@@ -831,6 +876,14 @@ void __init at91rm9200_pm_init(void)
831876
if (!IS_ENABLED(CONFIG_SOC_AT91RM9200))
832877
return;
833878

879+
/*
880+
* Force STANDBY and ULP0 mode to avoid calling
881+
* at91_pm_modes_validate() which may increase booting time.
882+
* Platform supports anyway only STANDBY and ULP0 modes.
883+
*/
884+
soc_pm.data.standby_mode = AT91_PM_STANDBY;
885+
soc_pm.data.suspend_mode = AT91_PM_ULP0;
886+
834887
at91_dt_ramc();
835888

836889
/*
@@ -843,9 +896,14 @@ void __init at91rm9200_pm_init(void)
843896

844897
void __init sam9x60_pm_init(void)
845898
{
899+
static const int modes[] __initconst = {
900+
AT91_PM_STANDBY, AT91_PM_ULP0, AT91_PM_ULP0_FAST, AT91_PM_ULP1,
901+
};
902+
846903
if (!IS_ENABLED(CONFIG_SOC_SAM9X60))
847904
return;
848905

906+
at91_pm_modes_validate(modes, ARRAY_SIZE(modes));
849907
at91_pm_modes_init();
850908
at91_dt_ramc();
851909
at91_pm_init(at91sam9x60_idle);
@@ -859,26 +917,46 @@ void __init at91sam9_pm_init(void)
859917
if (!IS_ENABLED(CONFIG_SOC_AT91SAM9))
860918
return;
861919

920+
/*
921+
* Force STANDBY and ULP0 mode to avoid calling
922+
* at91_pm_modes_validate() which may increase booting time.
923+
* Platform supports anyway only STANDBY and ULP0 modes.
924+
*/
925+
soc_pm.data.standby_mode = AT91_PM_STANDBY;
926+
soc_pm.data.suspend_mode = AT91_PM_ULP0;
927+
862928
at91_dt_ramc();
863929
at91_pm_init(at91sam9_idle);
864930
}
865931

866932
void __init sama5_pm_init(void)
867933
{
934+
static const int modes[] __initconst = {
935+
AT91_PM_STANDBY, AT91_PM_ULP0, AT91_PM_ULP0_FAST,
936+
};
937+
868938
if (!IS_ENABLED(CONFIG_SOC_SAMA5))
869939
return;
870940

941+
at91_pm_modes_validate(modes, ARRAY_SIZE(modes));
871942
at91_dt_ramc();
872943
at91_pm_init(NULL);
873944
}
874945

875946
void __init sama5d2_pm_init(void)
876947
{
948+
static const int modes[] __initconst = {
949+
AT91_PM_STANDBY, AT91_PM_ULP0, AT91_PM_ULP0_FAST, AT91_PM_ULP1,
950+
AT91_PM_BACKUP,
951+
};
952+
877953
if (!IS_ENABLED(CONFIG_SOC_SAMA5D2))
878954
return;
879955

956+
at91_pm_modes_validate(modes, ARRAY_SIZE(modes));
880957
at91_pm_modes_init();
881-
sama5_pm_init();
958+
at91_dt_ramc();
959+
at91_pm_init(NULL);
882960

883961
soc_pm.ws_ids = sama5d2_ws_ids;
884962
soc_pm.config_shdwc_ws = at91_sama5d2_config_shdwc_ws;

0 commit comments

Comments
 (0)