@@ -948,10 +948,63 @@ static const struct of_device_id atmel_shdwc_ids[] = {
948948 { /* sentinel. */ }
949949};
950950
951+ /*
952+ * Replaces _mode_to_replace with a supported mode that doesn't depend
953+ * on controller pointed by _map_bitmask
954+ * @_maps: u32 array containing AT91_PM_IOMAP() flags and indexed by AT91
955+ * PM mode
956+ * @_map_bitmask: AT91_PM_IOMAP() bitmask; if _mode_to_replace depends on
957+ * controller represented by _map_bitmask, _mode_to_replace needs to be
958+ * updated
959+ * @_mode_to_replace: standby_mode or suspend_mode that need to be
960+ * updated
961+ * @_mode_to_check: standby_mode or suspend_mode; this is needed here
962+ * to avoid having standby_mode and suspend_mode set with the same AT91
963+ * PM mode
964+ */
965+ #define AT91_PM_REPLACE_MODE (_maps , _map_bitmask , _mode_to_replace , \
966+ _mode_to_check ) \
967+ do { \
968+ if (((_maps)[(_mode_to_replace)]) & (_map_bitmask)) { \
969+ int _mode_to_use, _mode_complementary; \
970+ /* Use ULP0 if it doesn't need _map_bitmask. */ \
971+ if (!((_maps )[AT91_PM_ULP0 ] & (_map_bitmask ))) {\
972+ _mode_to_use = AT91_PM_ULP0 ; \
973+ _mode_complementary = AT91_PM_STANDBY ; \
974+ } else { \
975+ _mode_to_use = AT91_PM_STANDBY ; \
976+ _mode_complementary = AT91_PM_STANDBY ; \
977+ } \
978+ \
979+ if ((_mode_to_check ) != _mode_to_use ) \
980+ (_mode_to_replace ) = _mode_to_use ; \
981+ else \
982+ (_mode_to_replace ) = _mode_complementary ;\
983+ } \
984+ } while (0 )
985+
986+ /*
987+ * Replaces standby and suspend modes with default supported modes:
988+ * ULP0 and STANDBY.
989+ * @_maps: u32 array indexed by AT91 PM mode containing AT91_PM_IOMAP()
990+ * flags
991+ * @_map: controller specific name; standby and suspend mode need to be
992+ * replaced in order to not depend on this controller
993+ */
994+ #define AT91_PM_REPLACE_MODES (_maps , _map ) \
995+ do { \
996+ AT91_PM_REPLACE_MODE((_maps), BIT(AT91_PM_IOMAP_##_map),\
997+ (soc_pm.data.standby_mode), \
998+ (soc_pm.data.suspend_mode)); \
999+ AT91_PM_REPLACE_MODE((_maps), BIT(AT91_PM_IOMAP_##_map),\
1000+ (soc_pm.data.suspend_mode), \
1001+ (soc_pm.data.standby_mode)); \
1002+ } while (0)
1003+
9511004static void __init at91_pm_modes_init (const u32 * maps , int len )
9521005{
9531006 struct device_node * np ;
954- int ret , mode ;
1007+ int ret ;
9551008
9561009 ret = at91_pm_backup_init ();
9571010 if (ret ) {
@@ -966,17 +1019,7 @@ static void __init at91_pm_modes_init(const u32 *maps, int len)
9661019 np = of_find_matching_node (NULL , atmel_shdwc_ids );
9671020 if (!np ) {
9681021 pr_warn ("%s: failed to find shdwc!\n" , __func__ );
969-
970- /* Use ULP0 if it doesn't needs SHDWC.*/
971- if (!(maps [AT91_PM_ULP0 ] & AT91_PM_IOMAP (SHDWC )))
972- mode = AT91_PM_ULP0 ;
973- else
974- mode = AT91_PM_STANDBY ;
975-
976- if (maps [soc_pm .data .standby_mode ] & AT91_PM_IOMAP (SHDWC ))
977- soc_pm .data .standby_mode = mode ;
978- if (maps [soc_pm .data .suspend_mode ] & AT91_PM_IOMAP (SHDWC ))
979- soc_pm .data .suspend_mode = mode ;
1022+ AT91_PM_REPLACE_MODES (maps , SHDWC );
9801023 } else {
9811024 soc_pm .data .shdwc = of_iomap (np , 0 );
9821025 /*
@@ -992,21 +1035,7 @@ static void __init at91_pm_modes_init(const u32 *maps, int len)
9921035 np = of_find_compatible_node (NULL , NULL , "atmel,sama5d2-sfrbu" );
9931036 if (!np ) {
9941037 pr_warn ("%s: failed to find sfrbu!\n" , __func__ );
995-
996- /*
997- * Use ULP0 if it doesn't need SHDWC or if SHDWC
998- * was already located.
999- */
1000- if (!(maps [AT91_PM_ULP0 ] & AT91_PM_IOMAP (SHDWC )) ||
1001- soc_pm .data .shdwc )
1002- mode = AT91_PM_ULP0 ;
1003- else
1004- mode = AT91_PM_STANDBY ;
1005-
1006- if (maps [soc_pm .data .standby_mode ] & AT91_PM_IOMAP (SFRBU ))
1007- soc_pm .data .standby_mode = mode ;
1008- if (maps [soc_pm .data .suspend_mode ] & AT91_PM_IOMAP (SFRBU ))
1009- soc_pm .data .suspend_mode = mode ;
1038+ AT91_PM_REPLACE_MODES (maps , SFRBU );
10101039 } else {
10111040 soc_pm .data .sfrbu = of_iomap (np , 0 );
10121041 of_node_put (np );
0 commit comments