aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-at91/pm.c42
1 files changed, 34 insertions, 8 deletions
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index c83f78000ab3..27264caa4ec6 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -40,6 +40,9 @@ extern void at91_pinctrl_gpio_resume(void);
40#endif 40#endif
41 41
42struct at91_soc_pm { 42struct at91_soc_pm {
43 int (*config_shdwc_ws)(void __iomem *shdwc, u32 *mode, u32 *polarity);
44 int (*config_pmc_ws)(void __iomem *pmc, u32 mode, u32 polarity);
45 const struct of_device_id *ws_ids;
43 struct at91_pm_data data; 46 struct at91_pm_data data;
44}; 47};
45 48
@@ -122,7 +125,7 @@ static int at91_pm_config_ws(unsigned int pm_mode, bool set)
122 if (pm_mode != AT91_PM_ULP1) 125 if (pm_mode != AT91_PM_ULP1)
123 return 0; 126 return 0;
124 127
125 if (!soc_pm.data.pmc || !soc_pm.data.shdwc) 128 if (!soc_pm.data.pmc || !soc_pm.data.shdwc || !soc_pm.ws_ids)
126 return -EPERM; 129 return -EPERM;
127 130
128 if (!set) { 131 if (!set) {
@@ -130,16 +133,14 @@ static int at91_pm_config_ws(unsigned int pm_mode, bool set)
130 return 0; 133 return 0;
131 } 134 }
132 135
133 /* SHDWC.WUIR */ 136 if (soc_pm.config_shdwc_ws)
134 val = readl(soc_pm.data.shdwc + 0x0c); 137 soc_pm.config_shdwc_ws(soc_pm.data.shdwc, &mode, &polarity);
135 mode |= (val & 0x3ff);
136 polarity |= ((val >> 16) & 0x3ff);
137 138
138 /* SHDWC.MR */ 139 /* SHDWC.MR */
139 val = readl(soc_pm.data.shdwc + 0x04); 140 val = readl(soc_pm.data.shdwc + 0x04);
140 141
141 /* Loop through defined wakeup sources. */ 142 /* Loop through defined wakeup sources. */
142 for_each_matching_node_and_match(np, sama5d2_ws_ids, &match) { 143 for_each_matching_node_and_match(np, soc_pm.ws_ids, &match) {
143 pdev = of_find_device_by_node(np); 144 pdev = of_find_device_by_node(np);
144 if (!pdev) 145 if (!pdev)
145 continue; 146 continue;
@@ -161,8 +162,8 @@ put_device:
161 } 162 }
162 163
163 if (mode) { 164 if (mode) {
164 writel(mode, soc_pm.data.pmc + AT91_PMC_FSMR); 165 if (soc_pm.config_pmc_ws)
165 writel(polarity, soc_pm.data.pmc + AT91_PMC_FSPR); 166 soc_pm.config_pmc_ws(soc_pm.data.pmc, mode, polarity);
166 } else { 167 } else {
167 pr_err("AT91: PM: no ULP1 wakeup sources found!"); 168 pr_err("AT91: PM: no ULP1 wakeup sources found!");
168 } 169 }
@@ -170,6 +171,27 @@ put_device:
170 return mode ? 0 : -EPERM; 171 return mode ? 0 : -EPERM;
171} 172}
172 173
174static int at91_sama5d2_config_shdwc_ws(void __iomem *shdwc, u32 *mode,
175 u32 *polarity)
176{
177 u32 val;
178
179 /* SHDWC.WUIR */
180 val = readl(shdwc + 0x0c);
181 *mode |= (val & 0x3ff);
182 *polarity |= ((val >> 16) & 0x3ff);
183
184 return 0;
185}
186
187static int at91_sama5d2_config_pmc_ws(void __iomem *pmc, u32 mode, u32 polarity)
188{
189 writel(mode, pmc + AT91_PMC_FSMR);
190 writel(polarity, pmc + AT91_PMC_FSPR);
191
192 return 0;
193}
194
173/* 195/*
174 * Called after processes are frozen, but before we shutdown devices. 196 * Called after processes are frozen, but before we shutdown devices.
175 */ 197 */
@@ -796,6 +818,10 @@ void __init sama5d2_pm_init(void)
796 818
797 at91_pm_modes_init(); 819 at91_pm_modes_init();
798 sama5_pm_init(); 820 sama5_pm_init();
821
822 soc_pm.ws_ids = sama5d2_ws_ids;
823 soc_pm.config_shdwc_ws = at91_sama5d2_config_shdwc_ws;
824 soc_pm.config_pmc_ws = at91_sama5d2_config_pmc_ws;
799} 825}
800 826
801static int __init at91_pm_modes_select(char *str) 827static int __init at91_pm_modes_select(char *str)