ath25: switch default kernel to 5.15
[openwrt/openwrt.git] / target / linux / at91 / patches-5.10 / 200-ARM-at91-pm-check-for-different-controllers-in-at91_.patch
1 From 0c4cbd38a705bdeab11de4c84ad0ce8c3de8a81d Mon Sep 17 00:00:00 2001
2 From: Claudiu Beznea <claudiu.beznea@microchip.com>
3 Date: Thu, 15 Apr 2021 13:49:50 +0300
4 Subject: [PATCH 200/247] ARM: at91: pm: check for different controllers in
5 at91_pm_modes_init()
6
7 at91_pm_modes_init() checks for proper nodes in device tree and maps
8 them accordingly. Up to SAMA7G5 all AT91 SoCs had the same mapping
9 b/w power saving modes and different controllers needed in the
10 final/first steps of suspend/resume. SAMA7G5 is not aligned with the
11 old SoCs thus the code is adapted for this. This patch prepares
12 the field for next commits.
13
14 Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
15 Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com>
16 Link: https://lore.kernel.org/r/20210415105010.569620-5-claudiu.beznea@microchip.com
17 ---
18 arch/arm/mach-at91/pm.c | 143 +++++++++++++++++++++++++---------------
19 1 file changed, 91 insertions(+), 52 deletions(-)
20
21 --- a/arch/arm/mach-at91/pm.c
22 +++ b/arch/arm/mach-at91/pm.c
23 @@ -57,6 +57,18 @@ struct at91_soc_pm {
24 struct at91_pm_data data;
25 };
26
27 +/**
28 + * enum at91_pm_iomaps: IOs that needs to be mapped for different PM modes
29 + * @AT91_PM_IOMAP_SHDWC: SHDWC controller
30 + * @AT91_PM_IOMAP_SFRBU: SFRBU controller
31 + */
32 +enum at91_pm_iomaps {
33 + AT91_PM_IOMAP_SHDWC,
34 + AT91_PM_IOMAP_SFRBU,
35 +};
36 +
37 +#define AT91_PM_IOMAP(name) BIT(AT91_PM_IOMAP_##name)
38 +
39 static struct at91_soc_pm soc_pm = {
40 .data = {
41 .standby_mode = AT91_PM_STANDBY,
42 @@ -671,24 +683,15 @@ static int __init at91_pm_backup_init(vo
43 if (!at91_is_pm_mode_active(AT91_PM_BACKUP))
44 return 0;
45
46 - np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-sfrbu");
47 - if (!np) {
48 - pr_warn("%s: failed to find sfrbu!\n", __func__);
49 - return ret;
50 - }
51 -
52 - soc_pm.data.sfrbu = of_iomap(np, 0);
53 - of_node_put(np);
54 -
55 np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-securam");
56 if (!np)
57 - goto securam_fail_no_ref_dev;
58 + return ret;
59
60 pdev = of_find_device_by_node(np);
61 of_node_put(np);
62 if (!pdev) {
63 pr_warn("%s: failed to find securam device!\n", __func__);
64 - goto securam_fail_no_ref_dev;
65 + return ret;
66 }
67
68 sram_pool = gen_pool_get(&pdev->dev, NULL);
69 @@ -712,64 +715,92 @@ static int __init at91_pm_backup_init(vo
70
71 securam_fail:
72 put_device(&pdev->dev);
73 -securam_fail_no_ref_dev:
74 - iounmap(soc_pm.data.sfrbu);
75 - soc_pm.data.sfrbu = NULL;
76 return ret;
77 }
78
79 -static void __init at91_pm_use_default_mode(int pm_mode)
80 -{
81 - if (pm_mode != AT91_PM_ULP1 && pm_mode != AT91_PM_BACKUP)
82 - return;
83 -
84 - if (soc_pm.data.standby_mode == pm_mode)
85 - soc_pm.data.standby_mode = AT91_PM_ULP0;
86 - if (soc_pm.data.suspend_mode == pm_mode)
87 - soc_pm.data.suspend_mode = AT91_PM_ULP0;
88 -}
89 -
90 static const struct of_device_id atmel_shdwc_ids[] = {
91 { .compatible = "atmel,sama5d2-shdwc" },
92 { .compatible = "microchip,sam9x60-shdwc" },
93 { /* sentinel. */ }
94 };
95
96 -static void __init at91_pm_modes_init(void)
97 +static void __init at91_pm_modes_init(const u32 *maps, int len)
98 {
99 struct device_node *np;
100 - int ret;
101 + int ret, mode;
102
103 - if (!at91_is_pm_mode_active(AT91_PM_BACKUP) &&
104 - !at91_is_pm_mode_active(AT91_PM_ULP1))
105 - return;
106 + ret = at91_pm_backup_init();
107 + if (ret) {
108 + if (soc_pm.data.standby_mode == AT91_PM_BACKUP)
109 + soc_pm.data.standby_mode = AT91_PM_ULP0;
110 + if (soc_pm.data.suspend_mode == AT91_PM_BACKUP)
111 + soc_pm.data.suspend_mode = AT91_PM_ULP0;
112 + }
113 +
114 + if (maps[soc_pm.data.standby_mode] & AT91_PM_IOMAP(SHDWC) ||
115 + maps[soc_pm.data.suspend_mode] & AT91_PM_IOMAP(SHDWC)) {
116 + np = of_find_matching_node(NULL, atmel_shdwc_ids);
117 + if (!np) {
118 + pr_warn("%s: failed to find shdwc!\n", __func__);
119 +
120 + /* Use ULP0 if it doesn't needs SHDWC.*/
121 + if (!(maps[AT91_PM_ULP0] & AT91_PM_IOMAP(SHDWC)))
122 + mode = AT91_PM_ULP0;
123 + else
124 + mode = AT91_PM_STANDBY;
125 +
126 + if (maps[soc_pm.data.standby_mode] & AT91_PM_IOMAP(SHDWC))
127 + soc_pm.data.standby_mode = mode;
128 + if (maps[soc_pm.data.suspend_mode] & AT91_PM_IOMAP(SHDWC))
129 + soc_pm.data.suspend_mode = mode;
130 + } else {
131 + soc_pm.data.shdwc = of_iomap(np, 0);
132 + of_node_put(np);
133 + }
134 + }
135
136 - np = of_find_matching_node(NULL, atmel_shdwc_ids);
137 - if (!np) {
138 - pr_warn("%s: failed to find shdwc!\n", __func__);
139 - goto ulp1_default;
140 + if (maps[soc_pm.data.standby_mode] & AT91_PM_IOMAP(SFRBU) ||
141 + maps[soc_pm.data.suspend_mode] & AT91_PM_IOMAP(SFRBU)) {
142 + np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-sfrbu");
143 + if (!np) {
144 + pr_warn("%s: failed to find sfrbu!\n", __func__);
145 +
146 + /*
147 + * Use ULP0 if it doesn't need SHDWC or if SHDWC
148 + * was already located.
149 + */
150 + if (!(maps[AT91_PM_ULP0] & AT91_PM_IOMAP(SHDWC)) ||
151 + soc_pm.data.shdwc)
152 + mode = AT91_PM_ULP0;
153 + else
154 + mode = AT91_PM_STANDBY;
155 +
156 + if (maps[soc_pm.data.standby_mode] & AT91_PM_IOMAP(SFRBU))
157 + soc_pm.data.standby_mode = mode;
158 + if (maps[soc_pm.data.suspend_mode] & AT91_PM_IOMAP(SFRBU))
159 + soc_pm.data.suspend_mode = mode;
160 + } else {
161 + soc_pm.data.sfrbu = of_iomap(np, 0);
162 + of_node_put(np);
163 + }
164 }
165
166 - soc_pm.data.shdwc = of_iomap(np, 0);
167 - of_node_put(np);
168 + /* Unmap all unnecessary. */
169 + if (soc_pm.data.shdwc &&
170 + !(maps[soc_pm.data.standby_mode] & AT91_PM_IOMAP(SHDWC) ||
171 + maps[soc_pm.data.suspend_mode] & AT91_PM_IOMAP(SHDWC))) {
172 + iounmap(soc_pm.data.shdwc);
173 + soc_pm.data.shdwc = NULL;
174 + }
175
176 - ret = at91_pm_backup_init();
177 - if (ret) {
178 - if (!at91_is_pm_mode_active(AT91_PM_ULP1))
179 - goto unmap;
180 - else
181 - goto backup_default;
182 + if (soc_pm.data.sfrbu &&
183 + !(maps[soc_pm.data.standby_mode] & AT91_PM_IOMAP(SFRBU) ||
184 + maps[soc_pm.data.suspend_mode] & AT91_PM_IOMAP(SFRBU))) {
185 + iounmap(soc_pm.data.sfrbu);
186 + soc_pm.data.sfrbu = NULL;
187 }
188
189 return;
190 -
191 -unmap:
192 - iounmap(soc_pm.data.shdwc);
193 - soc_pm.data.shdwc = NULL;
194 -ulp1_default:
195 - at91_pm_use_default_mode(AT91_PM_ULP1);
196 -backup_default:
197 - at91_pm_use_default_mode(AT91_PM_BACKUP);
198 }
199
200 struct pmc_info {
201 @@ -936,13 +967,16 @@ void __init sam9x60_pm_init(void)
202 static const int modes[] __initconst = {
203 AT91_PM_STANDBY, AT91_PM_ULP0, AT91_PM_ULP0_FAST, AT91_PM_ULP1,
204 };
205 + static const int iomaps[] __initconst = {
206 + [AT91_PM_ULP1] = AT91_PM_IOMAP(SHDWC),
207 + };
208 int ret;
209
210 if (!IS_ENABLED(CONFIG_SOC_SAM9X60))
211 return;
212
213 at91_pm_modes_validate(modes, ARRAY_SIZE(modes));
214 - at91_pm_modes_init();
215 + at91_pm_modes_init(iomaps, ARRAY_SIZE(iomaps));
216 ret = at91_dt_ramc();
217 if (ret)
218 return;
219 @@ -999,13 +1033,18 @@ void __init sama5d2_pm_init(void)
220 AT91_PM_STANDBY, AT91_PM_ULP0, AT91_PM_ULP0_FAST, AT91_PM_ULP1,
221 AT91_PM_BACKUP,
222 };
223 + static const u32 iomaps[] __initconst = {
224 + [AT91_PM_ULP1] = AT91_PM_IOMAP(SHDWC),
225 + [AT91_PM_BACKUP] = AT91_PM_IOMAP(SHDWC) |
226 + AT91_PM_IOMAP(SFRBU),
227 + };
228 int ret;
229
230 if (!IS_ENABLED(CONFIG_SOC_SAMA5D2))
231 return;
232
233 at91_pm_modes_validate(modes, ARRAY_SIZE(modes));
234 - at91_pm_modes_init();
235 + at91_pm_modes_init(iomaps, ARRAY_SIZE(iomaps));
236 ret = at91_dt_ramc();
237 if (ret)
238 return;