35
35
36
36
#define AT91_RSTC_MR 0x08 /* Reset Controller Mode Register */
37
37
#define AT91_RSTC_URSTEN BIT(0) /* User Reset Enable */
38
+ #define AT91_RSTC_URSTASYNC BIT(2) /* User Reset Asynchronous Control */
38
39
#define AT91_RSTC_URSTIEN BIT(4) /* User Reset Interrupt Enable */
39
40
#define AT91_RSTC_ERSTL GENMASK(11, 8) /* External Reset Length */
40
41
@@ -49,105 +50,63 @@ enum reset_type {
49
50
RESET_TYPE_ULP2 = 8 ,
50
51
};
51
52
52
- static void __iomem * at91_ramc_base [2 ], * at91_rstc_base ;
53
- static struct clk * sclk ;
53
+ struct at91_reset {
54
+ void __iomem * rstc_base ;
55
+ void __iomem * ramc_base [2 ];
56
+ struct clk * sclk ;
57
+ struct notifier_block nb ;
58
+ u32 args ;
59
+ u32 ramc_lpr ;
60
+ };
54
61
55
62
/*
56
63
* unless the SDRAM is cleanly shutdown before we hit the
57
64
* reset register it can be left driving the data bus and
58
65
* killing the chance of a subsequent boot from NAND
59
66
*/
60
- static int at91sam9260_restart (struct notifier_block * this , unsigned long mode ,
61
- void * cmd )
67
+ static int at91_reset (struct notifier_block * this , unsigned long mode ,
68
+ void * cmd )
62
69
{
63
- asm volatile (
64
- /* Align to cache lines */
65
- ".balign 32\n\t"
66
-
67
- /* Disable SDRAM accesses */
68
- "str %2, [%0, #" __stringify (AT91_SDRAMC_TR ) "]\n\t"
69
-
70
- /* Power down SDRAM */
71
- "str %3, [%0, #" __stringify (AT91_SDRAMC_LPR ) "]\n\t"
72
-
73
- /* Reset CPU */
74
- "str %4, [%1, #" __stringify (AT91_RSTC_CR ) "]\n\t"
75
-
76
- "b .\n\t"
77
- :
78
- : "r" (at91_ramc_base [0 ]),
79
- "r" (at91_rstc_base ),
80
- "r" (1 ),
81
- "r" cpu_to_le32 (AT91_SDRAMC_LPCB_POWER_DOWN ),
82
- "r" cpu_to_le32 (AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST ));
70
+ struct at91_reset * reset = container_of (this , struct at91_reset , nb );
83
71
84
- return NOTIFY_DONE ;
85
- }
86
-
87
- static int at91sam9g45_restart (struct notifier_block * this , unsigned long mode ,
88
- void * cmd )
89
- {
90
72
asm volatile (
91
- /*
92
- * Test wether we have a second RAM controller to care
93
- * about.
94
- *
95
- * First, test that we can dereference the virtual address.
96
- */
97
- "cmp %1, #0\n\t"
98
- "beq 1f\n\t"
99
-
100
- /* Then, test that the RAM controller is enabled */
101
- "ldr r0, [%1]\n\t"
102
- "cmp r0, #0\n\t"
103
-
104
73
/* Align to cache lines */
105
74
".balign 32\n\t"
106
75
107
76
/* Disable SDRAM0 accesses */
108
- "1: str %3, [%0, #" __stringify (AT91_DDRSDRC_RTR ) "]\n\t"
77
+ " tst %0, #0\n\t"
78
+ " beq 1f\n\t"
79
+ " str %3, [%0, #" __stringify (AT91_DDRSDRC_RTR ) "]\n\t"
109
80
/* Power down SDRAM0 */
110
- " str %4, [%0, #" __stringify ( AT91_DDRSDRC_LPR ) " ]\n\t"
81
+ " str %4, [%0, %6 ]\n\t"
111
82
/* Disable SDRAM1 accesses */
83
+ "1: tst %1, #0\n\t"
84
+ " beq 2f\n\t"
112
85
" strne %3, [%1, #" __stringify (AT91_DDRSDRC_RTR ) "]\n\t"
113
86
/* Power down SDRAM1 */
114
- " strne %4, [%1, #" __stringify ( AT91_DDRSDRC_LPR ) " ]\n\t"
87
+ " strne %4, [%1, %6 ]\n\t"
115
88
/* Reset CPU */
116
- " str %5, [%2, #" __stringify (AT91_RSTC_CR ) "]\n\t"
89
+ "2: str %5, [%2, #" __stringify (AT91_RSTC_CR ) "]\n\t"
117
90
118
91
" b .\n\t"
119
92
:
120
- : "r" (at91_ramc_base [0 ]),
121
- "r" (at91_ramc_base [1 ]),
122
- "r" (at91_rstc_base ),
93
+ : "r" (reset -> ramc_base [0 ]),
94
+ "r" (reset -> ramc_base [1 ]),
95
+ "r" (reset -> rstc_base ),
123
96
"r" (1 ),
124
97
"r" cpu_to_le32 (AT91_DDRSDRC_LPCB_POWER_DOWN ),
125
- "r" cpu_to_le32 (AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST )
126
- : "r0" );
127
-
128
- return NOTIFY_DONE ;
129
- }
130
-
131
- static int sama5d3_restart (struct notifier_block * this , unsigned long mode ,
132
- void * cmd )
133
- {
134
- writel (AT91_RSTC_KEY | AT91_RSTC_PERRST | AT91_RSTC_PROCRST ,
135
- at91_rstc_base );
98
+ "r" (reset -> args ),
99
+ "r" (reset -> ramc_lpr )
100
+ : "r4" );
136
101
137
102
return NOTIFY_DONE ;
138
103
}
139
104
140
- static int samx7_restart (struct notifier_block * this , unsigned long mode ,
141
- void * cmd )
142
- {
143
- writel (AT91_RSTC_KEY | AT91_RSTC_PROCRST , at91_rstc_base );
144
- return NOTIFY_DONE ;
145
- }
146
-
147
- static void __init at91_reset_status (struct platform_device * pdev )
105
+ static void __init at91_reset_status (struct platform_device * pdev ,
106
+ void __iomem * base )
148
107
{
149
108
const char * reason ;
150
- u32 reg = readl (at91_rstc_base + AT91_RSTC_SR );
109
+ u32 reg = readl (base + AT91_RSTC_SR );
151
110
152
111
switch ((reg & AT91_RSTC_RSTTYP ) >> 8 ) {
153
112
case RESET_TYPE_GENERAL :
@@ -183,42 +142,68 @@ static void __init at91_reset_status(struct platform_device *pdev)
183
142
}
184
143
185
144
static const struct of_device_id at91_ramc_of_match [] = {
186
- { .compatible = "atmel,at91sam9260-sdramc" , },
187
- { .compatible = "atmel,at91sam9g45-ddramc" , },
145
+ {
146
+ .compatible = "atmel,at91sam9260-sdramc" ,
147
+ .data = (void * )AT91_SDRAMC_LPR ,
148
+ },
149
+ {
150
+ .compatible = "atmel,at91sam9g45-ddramc" ,
151
+ .data = (void * )AT91_DDRSDRC_LPR ,
152
+ },
188
153
{ /* sentinel */ }
189
154
};
190
155
191
156
static const struct of_device_id at91_reset_of_match [] = {
192
- { .compatible = "atmel,at91sam9260-rstc" , .data = at91sam9260_restart },
193
- { .compatible = "atmel,at91sam9g45-rstc" , .data = at91sam9g45_restart },
194
- { .compatible = "atmel,sama5d3-rstc" , .data = sama5d3_restart },
195
- { .compatible = "atmel,samx7-rstc" , .data = samx7_restart },
196
- { .compatible = "microchip,sam9x60-rstc" , .data = samx7_restart },
157
+ {
158
+ .compatible = "atmel,at91sam9260-rstc" ,
159
+ .data = (void * )(AT91_RSTC_KEY | AT91_RSTC_PERRST |
160
+ AT91_RSTC_PROCRST ),
161
+ },
162
+ {
163
+ .compatible = "atmel,at91sam9g45-rstc" ,
164
+ .data = (void * )(AT91_RSTC_KEY | AT91_RSTC_PERRST |
165
+ AT91_RSTC_PROCRST )
166
+ },
167
+ {
168
+ .compatible = "atmel,sama5d3-rstc" ,
169
+ .data = (void * )(AT91_RSTC_KEY | AT91_RSTC_PERRST |
170
+ AT91_RSTC_PROCRST )
171
+ },
172
+ {
173
+ .compatible = "atmel,samx7-rstc" ,
174
+ .data = (void * )(AT91_RSTC_KEY | AT91_RSTC_PROCRST )
175
+ },
176
+ {
177
+ .compatible = "microchip,sam9x60-rstc" ,
178
+ .data = (void * )(AT91_RSTC_KEY | AT91_RSTC_PROCRST )
179
+ },
197
180
{ /* sentinel */ }
198
181
};
199
182
MODULE_DEVICE_TABLE (of , at91_reset_of_match );
200
183
201
- static struct notifier_block at91_restart_nb = {
202
- .priority = 192 ,
203
- };
204
-
205
184
static int __init at91_reset_probe (struct platform_device * pdev )
206
185
{
207
186
const struct of_device_id * match ;
187
+ struct at91_reset * reset ;
208
188
struct device_node * np ;
209
189
int ret , idx = 0 ;
210
190
211
- at91_rstc_base = of_iomap (pdev -> dev .of_node , 0 );
212
- if (!at91_rstc_base ) {
191
+ reset = devm_kzalloc (& pdev -> dev , sizeof (* reset ), GFP_KERNEL );
192
+ if (!reset )
193
+ return - ENOMEM ;
194
+
195
+ reset -> rstc_base = of_iomap (pdev -> dev .of_node , 0 );
196
+ if (!reset -> rstc_base ) {
213
197
dev_err (& pdev -> dev , "Could not map reset controller address\n" );
214
198
return - ENODEV ;
215
199
}
216
200
217
201
if (!of_device_is_compatible (pdev -> dev .of_node , "atmel,sama5d3-rstc" )) {
218
202
/* we need to shutdown the ddr controller, so get ramc base */
219
- for_each_matching_node (np , at91_ramc_of_match ) {
220
- at91_ramc_base [idx ] = of_iomap (np , 0 );
221
- if (!at91_ramc_base [idx ]) {
203
+ for_each_matching_node_and_match (np , at91_ramc_of_match , & match ) {
204
+ reset -> ramc_lpr = (u32 )match -> data ;
205
+ reset -> ramc_base [idx ] = of_iomap (np , 0 );
206
+ if (!reset -> ramc_base [idx ]) {
222
207
dev_err (& pdev -> dev , "Could not map ram controller address\n" );
223
208
of_node_put (np );
224
209
return - ENODEV ;
@@ -228,33 +213,46 @@ static int __init at91_reset_probe(struct platform_device *pdev)
228
213
}
229
214
230
215
match = of_match_node (at91_reset_of_match , pdev -> dev .of_node );
231
- at91_restart_nb .notifier_call = match -> data ;
216
+ reset -> nb .notifier_call = at91_reset ;
217
+ reset -> nb .priority = 192 ;
218
+ reset -> args = (u32 )match -> data ;
232
219
233
- sclk = devm_clk_get (& pdev -> dev , NULL );
234
- if (IS_ERR (sclk ))
235
- return PTR_ERR (sclk );
220
+ reset -> sclk = devm_clk_get (& pdev -> dev , NULL );
221
+ if (IS_ERR (reset -> sclk ))
222
+ return PTR_ERR (reset -> sclk );
236
223
237
- ret = clk_prepare_enable (sclk );
224
+ ret = clk_prepare_enable (reset -> sclk );
238
225
if (ret ) {
239
226
dev_err (& pdev -> dev , "Could not enable slow clock\n" );
240
227
return ret ;
241
228
}
242
229
243
- ret = register_restart_handler (& at91_restart_nb );
230
+ platform_set_drvdata (pdev , reset );
231
+
232
+ if (of_device_is_compatible (pdev -> dev .of_node , "microchip,sam9x60-rstc" )) {
233
+ u32 val = readl (reset -> rstc_base + AT91_RSTC_MR );
234
+
235
+ writel (AT91_RSTC_KEY | AT91_RSTC_URSTASYNC | val ,
236
+ reset -> rstc_base + AT91_RSTC_MR );
237
+ }
238
+
239
+ ret = register_restart_handler (& reset -> nb );
244
240
if (ret ) {
245
- clk_disable_unprepare (sclk );
241
+ clk_disable_unprepare (reset -> sclk );
246
242
return ret ;
247
243
}
248
244
249
- at91_reset_status (pdev );
245
+ at91_reset_status (pdev , reset -> rstc_base );
250
246
251
247
return 0 ;
252
248
}
253
249
254
250
static int __exit at91_reset_remove (struct platform_device * pdev )
255
251
{
256
- unregister_restart_handler (& at91_restart_nb );
257
- clk_disable_unprepare (sclk );
252
+ struct at91_reset * reset = platform_get_drvdata (pdev );
253
+
254
+ unregister_restart_handler (& reset -> nb );
255
+ clk_disable_unprepare (reset -> sclk );
258
256
259
257
return 0 ;
260
258
}
0 commit comments