]> git.wh0rd.org - patches.git/blame - bfin-cleanup-reboot.patch
sync vapier-m
[patches.git] / bfin-cleanup-reboot.patch
CommitLineData
5e993f12 1Index: 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
26Index: 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");
62Index: 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+}
140Index: 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+}
173Index: 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
186Index: 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 */
257Index: 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+}
283Index: 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 /*
354Index: 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 /*
444Index: 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+}
467Index: 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 /*