Commit | Line | Data |
---|---|---|
2714d9a6 MH |
1 | /* |
2 | * arch/blackfin/kernel/reboot.c - handle shutdown/reboot | |
3 | * | |
4 | * Copyright 2004-2007 Analog Devices Inc. | |
5 | * | |
6 | * Licensed under the GPL-2 or later. | |
7 | */ | |
8 | ||
9 | #include <linux/interrupt.h> | |
10 | #include <asm/bfin-global.h> | |
11 | #include <asm/reboot.h> | |
cdbf4c3c | 12 | #include <asm/bfrom.h> |
2714d9a6 | 13 | |
6a42a910 MF |
14 | /* A system soft reset makes external memory unusable so force |
15 | * this function into L1. We use the compiler ssync here rather | |
16 | * than SSYNC() because it's safe (no interrupts and such) and | |
17 | * we save some L1. We do not need to force sanity in the SYSCR | |
18 | * register as the BMODE selection bit is cleared by the soft | |
19 | * reset while the Core B bit (on dual core parts) is cleared by | |
20 | * the core reset. | |
2714d9a6 | 21 | */ |
adab7eb8 | 22 | __attribute__ ((__l1_text__, __noreturn__)) |
a6595bf0 | 23 | static void bfin_reset(void) |
2714d9a6 | 24 | { |
b5affb01 | 25 | #ifndef CONFIG_BF60x |
80310392 MF |
26 | if (!ANOMALY_05000353 && !ANOMALY_05000386) |
27 | bfrom_SoftReset((void *)(L1_SCRATCH_START + L1_SCRATCH_LENGTH - 20)); | |
28 | ||
6a42a910 MF |
29 | /* Wait for completion of "system" events such as cache line |
30 | * line fills so that we avoid infinite stalls later on as | |
31 | * much as possible. This code is in L1, so it won't trigger | |
32 | * any such event after this point in time. | |
33 | */ | |
34 | __builtin_bfin_ssync(); | |
2714d9a6 | 35 | |
80310392 MF |
36 | /* Initiate System software reset. */ |
37 | bfin_write_SWRST(0x7); | |
444ad82b | 38 | |
80310392 MF |
39 | /* Due to the way reset is handled in the hardware, we need |
40 | * to delay for 10 SCLKS. The only reliable way to do this is | |
41 | * to calculate the CCLK/SCLK ratio and multiply 10. For now, | |
42 | * we'll assume worse case which is a 1:15 ratio. | |
43 | */ | |
44 | asm( | |
45 | "LSETUP (1f, 1f) LC0 = %0\n" | |
46 | "1: nop;" | |
47 | : | |
48 | : "a" (15 * 10) | |
49 | : "LC0", "LB0", "LT0" | |
50 | ); | |
444ad82b | 51 | |
80310392 MF |
52 | /* Clear System software reset */ |
53 | bfin_write_SWRST(0); | |
6a42a910 | 54 | |
80310392 | 55 | /* The BF526 ROM will crash during reset */ |
adab7eb8 | 56 | #if defined(__ADSPBF522__) || defined(__ADSPBF524__) || defined(__ADSPBF526__) |
b0d3dc12 MF |
57 | /* Seems to be fixed with newer parts though ... */ |
58 | if (__SILICON_REVISION__ < 1 && bfin_revid() < 1) | |
59 | bfin_read_SWRST(); | |
adab7eb8 | 60 | #endif |
80310392 MF |
61 | /* Wait for the SWRST write to complete. Cannot rely on SSYNC |
62 | * though as the System state is all reset now. | |
63 | */ | |
64 | asm( | |
65 | "LSETUP (1f, 1f) LC1 = %0\n" | |
66 | "1: nop;" | |
67 | : | |
68 | : "a" (15 * 1) | |
69 | : "LC1", "LB1", "LT1" | |
70 | ); | |
6a42a910 | 71 | |
adab7eb8 | 72 | while (1) |
6a42a910 | 73 | /* Issue core reset */ |
2714d9a6 | 74 | asm("raise 1"); |
b5affb01 BL |
75 | #else |
76 | while (1) | |
77 | bfin_write_RCU0_CTL(0x1); | |
78 | #endif | |
2714d9a6 MH |
79 | } |
80 | ||
81 | __attribute__((weak)) | |
82 | void native_machine_restart(char *cmd) | |
83 | { | |
84 | } | |
85 | ||
86 | void machine_restart(char *cmd) | |
87 | { | |
88 | native_machine_restart(cmd); | |
8f65873e GY |
89 | if (smp_processor_id()) |
90 | smp_call_function((void *)bfin_reset, 0, 1); | |
cdbf4c3c | 91 | else |
8f65873e | 92 | bfin_reset(); |
2714d9a6 MH |
93 | } |
94 | ||
95 | __attribute__((weak)) | |
96 | void native_machine_halt(void) | |
97 | { | |
98 | idle_with_irq_disabled(); | |
99 | } | |
100 | ||
101 | void machine_halt(void) | |
102 | { | |
103 | native_machine_halt(); | |
104 | } | |
105 | ||
106 | __attribute__((weak)) | |
107 | void native_machine_power_off(void) | |
108 | { | |
109 | idle_with_irq_disabled(); | |
110 | } | |
111 | ||
112 | void machine_power_off(void) | |
113 | { | |
114 | native_machine_power_off(); | |
115 | } |