initial import
[patches.git] / bfin-cleanup-reboot.patch
1 Index: include/asm-blackfin/reboot.h
2 ===================================================================
3 --- include/asm-blackfin/reboot.h (revision 0)
4 +++ include/asm-blackfin/reboot.h (revision 0)
5 @@ -0,0 +1,20 @@
6 +/*
7 + * include/asm-blackfin/reboot.h - shutdown/reboot header
8 + *
9 + * Copyright 2004-2007 Analog Devices Inc.
10 + *
11 + * Licensed under the GPL-2 or later.
12 + */
13 +
14 +#ifndef __ASM_REBOOT_H__
15 +#define __ASM_REBOOT_H__
16 +
17 +/* optional board specific hooks */
18 +extern void native_machine_restart(char *cmd);
19 +extern void native_machine_halt(void);
20 +extern void native_machine_power_off(void);
21 +
22 +/* common reboot workarounds */
23 +extern void bfin_gpio_reset_spi0_ssel1(void);
24 +
25 +#endif
26 Index: arch/blackfin/kernel/process.c
27 ===================================================================
28 --- arch/blackfin/kernel/process.c (revision 3549)
29 +++ arch/blackfin/kernel/process.c (working copy)
30 @@ -132,31 +132,6 @@
31 }
32 }
33
34 -void machine_restart(char *__unused)
35 -{
36 -#if defined(CONFIG_BFIN_ICACHE)
37 - bfin_write_IMEM_CONTROL(0x01);
38 - SSYNC();
39 -#endif
40 - bfin_reset();
41 - /* Dont do anything till the reset occurs */
42 - while (1) {
43 - SSYNC();
44 - }
45 -}
46 -
47 -void machine_halt(void)
48 -{
49 - for (;;)
50 - asm volatile ("idle");
51 -}
52 -
53 -void machine_power_off(void)
54 -{
55 - for (;;)
56 - asm volatile ("idle");
57 -}
58 -
59 void show_regs(struct pt_regs *regs)
60 {
61 printk(KERN_NOTICE "\n");
62 Index: arch/blackfin/kernel/reboot.c
63 ===================================================================
64 --- arch/blackfin/kernel/reboot.c (revision 0)
65 +++ arch/blackfin/kernel/reboot.c (revision 0)
66 @@ -0,0 +1,73 @@
67 +/*
68 + * arch/blackfin/kernel/reboot.c - handle shutdown/reboot
69 + *
70 + * Copyright 2004-2007 Analog Devices Inc.
71 + *
72 + * Licensed under the GPL-2 or later.
73 + */
74 +
75 +#include <linux/interrupt.h>
76 +#include <asm/bfin-global.h>
77 +#include <asm/reboot.h>
78 +
79 +static void bfin_spin_forever(void)
80 +{
81 + while (1)
82 + asm volatile ("idle");
83 +}
84 +
85 +/* A system soft reset makes external memory unusable
86 + * so force this function into L1.
87 + */
88 +__attribute__((l1_text))
89 +void bfin_reset(void)
90 +{
91 + /* force BMODE and disable Core B (as needed) */
92 + bfin_write_SYSCR(0x20);
93 + while (1) {
94 + /* initiate system soft reset with magic 0x7 */
95 + bfin_write_SWRST(0x7);
96 + SSYNC();
97 + /* clear system soft reset */
98 + bfin_write_SWRST(0);
99 + SSYNC();
100 + /* issue core reset */
101 + asm("raise 1");
102 + }
103 +}
104 +
105 +__attribute__((weak))
106 +void native_machine_restart(char *cmd)
107 +{
108 +}
109 +
110 +void machine_restart(char *cmd)
111 +{
112 + native_machine_restart(cmd);
113 + local_irq_disable();
114 + bfin_reset();
115 +}
116 +
117 +__attribute__((weak))
118 +void native_machine_halt(void)
119 +{
120 + local_irq_disable();
121 + bfin_spin_forever();
122 +}
123 +
124 +void machine_halt(void)
125 +{
126 + native_machine_halt();
127 +}
128 +
129 +__attribute__((weak))
130 +void native_machine_power_off(void)
131 +{
132 + local_irq_disable();
133 + bfin_spin_forever();
134 +}
135 +
136 +void machine_power_off(void)
137 +{
138 + native_machine_power_off();
139 +}
140 Index: arch/blackfin/kernel/bfin_gpio.c
141 ===================================================================
142 --- arch/blackfin/kernel/bfin_gpio.c (revision 3549)
143 +++ arch/blackfin/kernel/bfin_gpio.c (working copy)
144 @@ -80,6 +80,7 @@
145 * GPIO_47 PH15 PF47
146 */
147
148 +#include <linux/delay.h>
149 #include <linux/module.h>
150 #include <linux/err.h>
151 #include <asm/blackfin.h>
152 @@ -888,3 +889,20 @@
153 local_irq_restore(flags);
154 }
155 EXPORT_SYMBOL(gpio_direction_output);
156 +
157 +/* If we are booting from SPI and our board lacks a strong enough pull up,
158 + * the core can reset and execute the bootrom faster than the resistor can
159 + * pull the signal logically high. To work around this (common) error in
160 + * board design, we explicitly set the pin back to GPIO mode, force /CS
161 + * high, and wait for the electrons to do their thing.
162 + *
163 + * This function only makes sense to be called from reset code, but it
164 + * lives here as we need to force all the GPIO states w/out going through
165 + * BUG() checks and such.
166 + */
167 +void bfin_gpio_reset_spi0_ssel1(void)
168 +{
169 + port_setup(P_SPI0_SSEL1, GPIO_USAGE);
170 + gpio_bankb[gpio_bank(P_SPI0_SSEL1)]->data_set = gpio_bit(P_SPI0_SSEL1);
171 + udelay(1);
172 +}
173 Index: arch/blackfin/kernel/Makefile
174 ===================================================================
175 --- arch/blackfin/kernel/Makefile (revision 3549)
176 +++ arch/blackfin/kernel/Makefile (working copy)
177 @@ -7,7 +7,7 @@
178 obj-y := \
179 entry.o process.o bfin_ksyms.o ptrace.o setup.o signal.o \
180 sys_bfin.o time.o traps.o irqchip.o dma-mapping.o flat.o \
181 - fixed_code.o cplbinit.o cacheinit.o
182 + fixed_code.o cplbinit.o cacheinit.o reboot.o
183
184 obj-$(CONFIG_BF53x) += bfin_gpio.o
185 obj-$(CONFIG_BF561) += bfin_gpio.o
186 Index: arch/blackfin/mach-bf533/head.S
187 ===================================================================
188 --- arch/blackfin/mach-bf533/head.S (revision 3549)
189 +++ arch/blackfin/mach-bf533/head.S (working copy)
190 @@ -459,66 +459,6 @@
191 ENDPROC(_start_dma_code)
192 #endif /* CONFIG_BFIN_KERNEL_CLOCK */
193
194 -ENTRY(_bfin_reset)
195 - /* No more interrupts to be handled*/
196 - CLI R6;
197 - SSYNC;
198 -
199 -#if defined(CONFIG_BFIN_SHARED_FLASH_ENET)
200 - p0.h = hi(FIO_INEN);
201 - p0.l = lo(FIO_INEN);
202 - r0.l = ~(1 << CONFIG_ENET_FLASH_PIN);
203 - w[p0] = r0.l;
204 -
205 - p0.h = hi(FIO_DIR);
206 - p0.l = lo(FIO_DIR);
207 - r0.l = (1 << CONFIG_ENET_FLASH_PIN);
208 - w[p0] = r0.l;
209 -
210 - p0.h = hi(FIO_FLAG_C);
211 - p0.l = lo(FIO_FLAG_C);
212 - r0.l = (1 << CONFIG_ENET_FLASH_PIN);
213 - w[p0] = r0.l;
214 -#endif
215 -
216 - /* Clear the IMASK register */
217 - p0.h = hi(IMASK);
218 - p0.l = lo(IMASK);
219 - r0 = 0x0;
220 - [p0] = r0;
221 -
222 - /* Clear the ILAT register */
223 - p0.h = hi(ILAT);
224 - p0.l = lo(ILAT);
225 - r0 = [p0];
226 - [p0] = r0;
227 - SSYNC;
228 -
229 - /* make sure SYSCR is set to use BMODE */
230 - P0.h = hi(SYSCR);
231 - P0.l = lo(SYSCR);
232 - R0.l = 0x0;
233 - W[P0] = R0.l;
234 - SSYNC;
235 -
236 - /* issue a system soft reset */
237 - P1.h = hi(SWRST);
238 - P1.l = lo(SWRST);
239 - R1.l = 0x0007;
240 - W[P1] = R1;
241 - SSYNC;
242 -
243 - /* clear system soft reset */
244 - R0.l = 0x0000;
245 - W[P0] = R0;
246 - SSYNC;
247 -
248 - /* issue core reset */
249 - raise 1;
250 -
251 - RTS;
252 -ENDPROC(_bfin_reset)
253 -
254 #if CONFIG_DEBUG_KERNEL_START
255 debug_kernel_start_trap:
256 /* Set up a temp stack in L1 - SDRAM might not be working */
257 Index: arch/blackfin/mach-bf533/boards/stamp.c
258 ===================================================================
259 --- arch/blackfin/mach-bf533/boards/stamp.c (revision 3549)
260 +++ arch/blackfin/mach-bf533/boards/stamp.c (working copy)
261 @@ -41,6 +41,7 @@
262 #include <linux/irq.h>
263 #include <asm/dma.h>
264 #include <asm/bfin5xx_spi.h>
265 +#include <asm/reboot.h>
266
267 /*
268 * Name the Board for the /proc/cpuinfo
269 @@ -424,3 +425,13 @@
270 }
271
272 arch_initcall(stamp_init);
273 +
274 +void native_machine_restart(char *cmd)
275 +{
276 +#if defined(CONFIG_BFIN_SHARED_FLASH_ENET)
277 +# define BIT_TO_SET (1 << CONFIG_ENET_FLASH_PIN)
278 + bfin_write_FIO_INEN(~BIT_TO_SET);
279 + bfin_write_FIO_DIR(BIT_TO_SET);
280 + bfin_write_FIO_FLAG_C(BIT_TO_SET);
281 +#endif
282 +}
283 Index: arch/blackfin/mach-bf561/head.S
284 ===================================================================
285 --- arch/blackfin/mach-bf561/head.S (revision 3549)
286 +++ arch/blackfin/mach-bf561/head.S (working copy)
287 @@ -406,66 +406,6 @@
288 ENDPROC(_start_dma_code)
289 #endif /* CONFIG_BFIN_KERNEL_CLOCK */
290
291 -ENTRY(_bfin_reset)
292 - /* No more interrupts to be handled*/
293 - CLI R6;
294 - SSYNC;
295 -
296 -#if defined(CONFIG_BFIN_SHARED_FLASH_ENET)
297 - p0.h = hi(FIO_INEN);
298 - p0.l = lo(FIO_INEN);
299 - r0.l = ~(PF1 | PF0);
300 - w[p0] = r0.l;
301 -
302 - p0.h = hi(FIO_DIR);
303 - p0.l = lo(FIO_DIR);
304 - r0.l = (PF1 | PF0);
305 - w[p0] = r0.l;
306 -
307 - p0.h = hi(FIO_FLAG_C);
308 - p0.l = lo(FIO_FLAG_C);
309 - r0.l = (PF1 | PF0);
310 - w[p0] = r0.l;
311 -#endif
312 -
313 - /* Clear the IMASK register */
314 - p0.h = hi(IMASK);
315 - p0.l = lo(IMASK);
316 - r0 = 0x0;
317 - [p0] = r0;
318 -
319 - /* Clear the ILAT register */
320 - p0.h = hi(ILAT);
321 - p0.l = lo(ILAT);
322 - r0 = [p0];
323 - [p0] = r0;
324 - SSYNC;
325 -
326 - /* make sure SYSCR is set to use BMODE */
327 - P0.h = hi(SYSCR);
328 - P0.l = lo(SYSCR);
329 - R0.l = 0x20; /* on BF561, disable core b */
330 - W[P0] = R0.l;
331 - SSYNC;
332 -
333 - /* issue a system soft reset */
334 - P1.h = hi(SWRST);
335 - P1.l = lo(SWRST);
336 - R1.l = 0x0007;
337 - W[P1] = R1;
338 - SSYNC;
339 -
340 - /* clear system soft reset */
341 - R0.l = 0x0000;
342 - W[P0] = R0;
343 - SSYNC;
344 -
345 - /* issue core reset */
346 - raise 1;
347 -
348 - RTS;
349 -ENDPROC(_bfin_reset)
350 -
351 .data
352
353 /*
354 Index: arch/blackfin/mach-bf537/head.S
355 ===================================================================
356 --- arch/blackfin/mach-bf537/head.S (revision 3549)
357 +++ arch/blackfin/mach-bf537/head.S (working copy)
358 @@ -478,85 +478,6 @@
359 ENDPROC(_start_dma_code)
360 #endif /* CONFIG_BFIN_KERNEL_CLOCK */
361
362 -ENTRY(_bfin_reset)
363 - /* No more interrupts to be handled*/
364 - CLI R6;
365 - SSYNC;
366 -
367 -#if defined(CONFIG_MTD_M25P80)
368 - /*
369 - * The following code fix the SPI flash reboot issue,
370 - * /CS signal of the chip which is using PF10 return to GPIO mode
371 - */
372 - p0.h = hi(PORTF_FER);
373 - p0.l = lo(PORTF_FER);
374 - r0.l = 0x0000;
375 - w[p0] = r0.l;
376 - SSYNC;
377 -
378 - /* /CS return to high */
379 - p0.h = hi(PORTFIO);
380 - p0.l = lo(PORTFIO);
381 - r0.l = 0xFFFF;
382 - w[p0] = r0.l;
383 - SSYNC;
384 -
385 - /* Delay some time, This is necessary */
386 - r1.h = 0;
387 - r1.l = 0x400;
388 - p1 = r1;
389 - lsetup (.L_delay_lab1, .L_delay_lab1_end) lc1 = p1;
390 -.L_delay_lab1:
391 - r0.h = 0;
392 - r0.l = 0x8000;
393 - p0 = r0;
394 - lsetup (.L_delay_lab0, .L_delay_lab0_end) lc0 = p0;
395 -.L_delay_lab0:
396 - nop;
397 -.L_delay_lab0_end:
398 - nop;
399 -.L_delay_lab1_end:
400 - nop;
401 -#endif
402 -
403 - /* Clear the IMASK register */
404 - p0.h = hi(IMASK);
405 - p0.l = lo(IMASK);
406 - r0 = 0x0;
407 - [p0] = r0;
408 -
409 - /* Clear the ILAT register */
410 - p0.h = hi(ILAT);
411 - p0.l = lo(ILAT);
412 - r0 = [p0];
413 - [p0] = r0;
414 - SSYNC;
415 -
416 - /* make sure SYSCR is set to use BMODE */
417 - P0.h = hi(SYSCR);
418 - P0.l = lo(SYSCR);
419 - R0.l = 0x0;
420 - W[P0] = R0.l;
421 - SSYNC;
422 -
423 - /* issue a system soft reset */
424 - P1.h = hi(SWRST);
425 - P1.l = lo(SWRST);
426 - R1.l = 0x0007;
427 - W[P1] = R1;
428 - SSYNC;
429 -
430 - /* clear system soft reset */
431 - R0.l = 0x0000;
432 - W[P0] = R0;
433 - SSYNC;
434 -
435 - /* issue core reset */
436 - raise 1;
437 -
438 - RTS;
439 -ENDPROC(_bfin_reset)
440 -
441 .data
442
443 /*
444 Index: arch/blackfin/mach-bf537/boards/stamp.c
445 ===================================================================
446 --- arch/blackfin/mach-bf537/boards/stamp.c (revision 3549)
447 +++ arch/blackfin/mach-bf537/boards/stamp.c (working copy)
448 @@ -43,6 +43,7 @@
449 #include <linux/usb_sl811.h>
450 #include <asm/dma.h>
451 #include <asm/bfin5xx_spi.h>
452 +#include <asm/reboot.h>
453 #include <linux/spi/ad7877.h>
454
455 /*
456 @@ -714,3 +715,10 @@
457 }
458
459 arch_initcall(stamp_init);
460 +
461 +void native_machine_restart(char *cmd)
462 +{
463 + /* workaround reboot hang when booting from SPI */
464 + if ((bfin_read_SYSCR() & 0x7) == 0x3)
465 + bfin_gpio_reset_spi0_ssel1();
466 +}
467 Index: arch/blackfin/mach-bf548/head.S
468 ===================================================================
469 --- arch/blackfin/mach-bf548/head.S (revision 3549)
470 +++ arch/blackfin/mach-bf548/head.S (working copy)
471 @@ -378,131 +378,6 @@
472 RTS;
473 #endif /* CONFIG_BFIN_KERNEL_CLOCK */
474
475 -ENTRY(_bfin_reset)
476 - /* No more interrupts to be handled*/
477 - CLI R6;
478 - SSYNC;
479 -
480 -#if 0 /* Need to determine later if this is here necessary for BF54x */
481 -#if defined(CONFIG_MTD_M25P80)
482 -/*
483 - * The following code fix the SPI flash reboot issue,
484 - * /CS signal of the chip which is using PF10 return to GPIO mode
485 - */
486 - p0.h = hi(PORTF_FER);
487 - p0.l = lo(PORTF_FER);
488 - r0.l = 0x0000;
489 - w[p0] = r0.l;
490 - SSYNC;
491 -
492 -/* /CS return to high */
493 - p0.h = hi(PORTFIO);
494 - p0.l = lo(PORTFIO);
495 - r0.l = 0xFFFF;
496 - w[p0] = r0.l;
497 - SSYNC;
498 -
499 -/* Delay some time, This is necessary */
500 - r1.h = 0;
501 - r1.l = 0x400;
502 - p1 = r1;
503 - lsetup (_delay_lab1,_delay_lab1_end ) lc1 = p1;
504 -_delay_lab1:
505 - r0.h = 0;
506 - r0.l = 0x8000;
507 - p0 = r0;
508 - lsetup (_delay_lab0,_delay_lab0_end ) lc0 = p0;
509 -_delay_lab0:
510 - nop;
511 -_delay_lab0_end:
512 - nop;
513 -_delay_lab1_end:
514 - nop;
515 -#endif
516 -#endif
517 -
518 - /* Clear the bits 13-15 in SWRST if they werent cleared */
519 - p0.h = hi(SWRST);
520 - p0.l = lo(SWRST);
521 - csync;
522 - r0.l = w[p0];
523 -
524 - /* Clear the IMASK register */
525 - p0.h = hi(IMASK);
526 - p0.l = lo(IMASK);
527 - r0 = 0x0;
528 - [p0] = r0;
529 -
530 - /* Clear the ILAT register */
531 - p0.h = hi(ILAT);
532 - p0.l = lo(ILAT);
533 - r0 = [p0];
534 - [p0] = r0;
535 - SSYNC;
536 -
537 - /* Disable the WDOG TIMER */
538 - p0.h = hi(WDOG_CTL);
539 - p0.l = lo(WDOG_CTL);
540 - r0.l = 0xAD6;
541 - w[p0] = r0.l;
542 - SSYNC;
543 -
544 - /* Clear the sticky bit incase it is already set */
545 - p0.h = hi(WDOG_CTL);
546 - p0.l = lo(WDOG_CTL);
547 - r0.l = 0x8AD6;
548 - w[p0] = r0.l;
549 - SSYNC;
550 -
551 - /* Program the count value */
552 - R0.l = 0x100;
553 - R0.h = 0x0;
554 - P0.h = hi(WDOG_CNT);
555 - P0.l = lo(WDOG_CNT);
556 - [P0] = R0;
557 - SSYNC;
558 -
559 - /* Program WDOG_STAT if necessary */
560 - P0.h = hi(WDOG_CTL);
561 - P0.l = lo(WDOG_CTL);
562 - R0 = W[P0](Z);
563 - CC = BITTST(R0,1);
564 - if !CC JUMP .LWRITESTAT;
565 - CC = BITTST(R0,2);
566 - if !CC JUMP .LWRITESTAT;
567 - JUMP .LSKIP_WRITE;
568 -
569 -.LWRITESTAT:
570 - /* When watch dog timer is enabled,
571 - * a write to STAT will load the contents of CNT to STAT
572 - */
573 - R0 = 0x0000(z);
574 - P0.h = hi(WDOG_STAT);
575 - P0.l = lo(WDOG_STAT)
576 - [P0] = R0;
577 - SSYNC;
578 -
579 -.LSKIP_WRITE:
580 - /* Enable the reset event */
581 - P0.h = hi(WDOG_CTL);
582 - P0.l = lo(WDOG_CTL);
583 - R0 = W[P0](Z);
584 - BITCLR(R0,1);
585 - BITCLR(R0,2);
586 - W[P0] = R0.L;
587 - SSYNC;
588 - NOP;
589 -
590 - /* Enable the wdog counter */
591 - R0 = W[P0](Z);
592 - BITCLR(R0,4);
593 - W[P0] = R0.L;
594 - SSYNC;
595 -
596 - IDLE;
597 -
598 - RTS;
599 -
600 .data
601
602 /*