aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/blackfin/include/asm/cplb.h46
-rw-r--r--arch/blackfin/kernel/cplb-mpu/cacheinit.c6
-rw-r--r--arch/blackfin/kernel/cplb-mpu/cplbmgr.c61
-rw-r--r--arch/blackfin/kernel/cplb-nompu/cacheinit.c6
-rw-r--r--arch/blackfin/kernel/cplb-nompu/cplbmgr.c33
-rw-r--r--arch/blackfin/mach-bf561/secondary.S20
-rw-r--r--arch/blackfin/mach-common/entry.S14
-rw-r--r--arch/blackfin/mach-common/pm.c64
8 files changed, 84 insertions, 166 deletions
diff --git a/arch/blackfin/include/asm/cplb.h b/arch/blackfin/include/asm/cplb.h
index c5dacf8f8cf9..d18d16837a6d 100644
--- a/arch/blackfin/include/asm/cplb.h
+++ b/arch/blackfin/include/asm/cplb.h
@@ -125,4 +125,48 @@
125#define FAULT_USERSUPV (1 << 17) 125#define FAULT_USERSUPV (1 << 17)
126#define FAULT_CPLBBITS 0x0000ffff 126#define FAULT_CPLBBITS 0x0000ffff
127 127
128#endif /* _CPLB_H */ 128#ifndef __ASSEMBLY__
129
130static inline void _disable_cplb(u32 mmr, u32 mask)
131{
132 u32 ctrl = bfin_read32(mmr) & ~mask;
133 /* CSYNC to ensure load store ordering */
134 __builtin_bfin_csync();
135 bfin_write32(mmr, ctrl);
136 __builtin_bfin_ssync();
137}
138static inline void disable_cplb(u32 mmr, u32 mask)
139{
140 u32 ctrl = bfin_read32(mmr) & ~mask;
141 CSYNC();
142 bfin_write32(mmr, ctrl);
143 SSYNC();
144}
145#define _disable_dcplb() _disable_cplb(DMEM_CONTROL, ENDCPLB)
146#define disable_dcplb() disable_cplb(DMEM_CONTROL, ENDCPLB)
147#define _disable_icplb() _disable_cplb(IMEM_CONTROL, ENICPLB)
148#define disable_icplb() disable_cplb(IMEM_CONTROL, ENICPLB)
149
150static inline void _enable_cplb(u32 mmr, u32 mask)
151{
152 u32 ctrl = bfin_read32(mmr) | mask;
153 /* CSYNC to ensure load store ordering */
154 __builtin_bfin_csync();
155 bfin_write32(mmr, ctrl);
156 __builtin_bfin_ssync();
157}
158static inline void enable_cplb(u32 mmr, u32 mask)
159{
160 u32 ctrl = bfin_read32(mmr) | mask;
161 CSYNC();
162 bfin_write32(mmr, ctrl);
163 SSYNC();
164}
165#define _enable_dcplb() _enable_cplb(DMEM_CONTROL, ENDCPLB)
166#define enable_dcplb() enable_cplb(DMEM_CONTROL, ENDCPLB)
167#define _enable_icplb() _enable_cplb(IMEM_CONTROL, ENICPLB)
168#define enable_icplb() enable_cplb(IMEM_CONTROL, ENICPLB)
169
170#endif /* __ASSEMBLY__ */
171
172#endif /* _CPLB_H */
diff --git a/arch/blackfin/kernel/cplb-mpu/cacheinit.c b/arch/blackfin/kernel/cplb-mpu/cacheinit.c
index d5a86c3017f7..a082681faa8e 100644
--- a/arch/blackfin/kernel/cplb-mpu/cacheinit.c
+++ b/arch/blackfin/kernel/cplb-mpu/cacheinit.c
@@ -30,13 +30,14 @@ void __cpuinit bfin_icache_init(struct cplb_entry *icplb_tbl)
30 unsigned long ctrl; 30 unsigned long ctrl;
31 int i; 31 int i;
32 32
33 SSYNC();
34 for (i = 0; i < MAX_CPLBS; i++) { 33 for (i = 0; i < MAX_CPLBS; i++) {
35 bfin_write32(ICPLB_ADDR0 + i * 4, icplb_tbl[i].addr); 34 bfin_write32(ICPLB_ADDR0 + i * 4, icplb_tbl[i].addr);
36 bfin_write32(ICPLB_DATA0 + i * 4, icplb_tbl[i].data); 35 bfin_write32(ICPLB_DATA0 + i * 4, icplb_tbl[i].data);
37 } 36 }
38 ctrl = bfin_read_IMEM_CONTROL(); 37 ctrl = bfin_read_IMEM_CONTROL();
39 ctrl |= IMC | ENICPLB; 38 ctrl |= IMC | ENICPLB;
39 /* CSYNC to ensure load store ordering */
40 CSYNC();
40 bfin_write_IMEM_CONTROL(ctrl); 41 bfin_write_IMEM_CONTROL(ctrl);
41 SSYNC(); 42 SSYNC();
42} 43}
@@ -48,7 +49,6 @@ void __cpuinit bfin_dcache_init(struct cplb_entry *dcplb_tbl)
48 unsigned long ctrl; 49 unsigned long ctrl;
49 int i; 50 int i;
50 51
51 SSYNC();
52 for (i = 0; i < MAX_CPLBS; i++) { 52 for (i = 0; i < MAX_CPLBS; i++) {
53 bfin_write32(DCPLB_ADDR0 + i * 4, dcplb_tbl[i].addr); 53 bfin_write32(DCPLB_ADDR0 + i * 4, dcplb_tbl[i].addr);
54 bfin_write32(DCPLB_DATA0 + i * 4, dcplb_tbl[i].data); 54 bfin_write32(DCPLB_DATA0 + i * 4, dcplb_tbl[i].data);
@@ -63,6 +63,8 @@ void __cpuinit bfin_dcache_init(struct cplb_entry *dcplb_tbl)
63 * to port B 63 * to port B
64 */ 64 */
65 ctrl |= DMEM_CNTR | PORT_PREF0 | (ANOMALY_05000287 ? PORT_PREF1 : 0); 65 ctrl |= DMEM_CNTR | PORT_PREF0 | (ANOMALY_05000287 ? PORT_PREF1 : 0);
66 /* CSYNC to ensure load store ordering */
67 CSYNC();
66 bfin_write_DMEM_CONTROL(ctrl); 68 bfin_write_DMEM_CONTROL(ctrl);
67 SSYNC(); 69 SSYNC();
68} 70}
diff --git a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
index bcdfe9b0b71f..651b12773e09 100644
--- a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
+++ b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
@@ -22,6 +22,7 @@
22 22
23#include <asm/blackfin.h> 23#include <asm/blackfin.h>
24#include <asm/cacheflush.h> 24#include <asm/cacheflush.h>
25#include <asm/cplb.h>
25#include <asm/cplbinit.h> 26#include <asm/cplbinit.h>
26#include <asm/mmu_context.h> 27#include <asm/mmu_context.h>
27 28
@@ -41,46 +42,6 @@ int nr_dcplb_miss[NR_CPUS], nr_icplb_miss[NR_CPUS];
41int nr_icplb_supv_miss[NR_CPUS], nr_dcplb_prot[NR_CPUS]; 42int nr_icplb_supv_miss[NR_CPUS], nr_dcplb_prot[NR_CPUS];
42int nr_cplb_flush[NR_CPUS]; 43int nr_cplb_flush[NR_CPUS];
43 44
44static inline void disable_dcplb(void)
45{
46 unsigned long ctrl;
47 SSYNC();
48 ctrl = bfin_read_DMEM_CONTROL();
49 ctrl &= ~ENDCPLB;
50 bfin_write_DMEM_CONTROL(ctrl);
51 SSYNC();
52}
53
54static inline void enable_dcplb(void)
55{
56 unsigned long ctrl;
57 SSYNC();
58 ctrl = bfin_read_DMEM_CONTROL();
59 ctrl |= ENDCPLB;
60 bfin_write_DMEM_CONTROL(ctrl);
61 SSYNC();
62}
63
64static inline void disable_icplb(void)
65{
66 unsigned long ctrl;
67 SSYNC();
68 ctrl = bfin_read_IMEM_CONTROL();
69 ctrl &= ~ENICPLB;
70 bfin_write_IMEM_CONTROL(ctrl);
71 SSYNC();
72}
73
74static inline void enable_icplb(void)
75{
76 unsigned long ctrl;
77 SSYNC();
78 ctrl = bfin_read_IMEM_CONTROL();
79 ctrl |= ENICPLB;
80 bfin_write_IMEM_CONTROL(ctrl);
81 SSYNC();
82}
83
84/* 45/*
85 * Given the contents of the status register, return the index of the 46 * Given the contents of the status register, return the index of the
86 * CPLB that caused the fault. 47 * CPLB that caused the fault.
@@ -198,10 +159,10 @@ static noinline int dcplb_miss(unsigned int cpu)
198 dcplb_tbl[cpu][idx].addr = addr; 159 dcplb_tbl[cpu][idx].addr = addr;
199 dcplb_tbl[cpu][idx].data = d_data; 160 dcplb_tbl[cpu][idx].data = d_data;
200 161
201 disable_dcplb(); 162 _disable_dcplb();
202 bfin_write32(DCPLB_DATA0 + idx * 4, d_data); 163 bfin_write32(DCPLB_DATA0 + idx * 4, d_data);
203 bfin_write32(DCPLB_ADDR0 + idx * 4, addr); 164 bfin_write32(DCPLB_ADDR0 + idx * 4, addr);
204 enable_dcplb(); 165 _enable_dcplb();
205 166
206 return 0; 167 return 0;
207} 168}
@@ -288,10 +249,10 @@ static noinline int icplb_miss(unsigned int cpu)
288 icplb_tbl[cpu][idx].addr = addr; 249 icplb_tbl[cpu][idx].addr = addr;
289 icplb_tbl[cpu][idx].data = i_data; 250 icplb_tbl[cpu][idx].data = i_data;
290 251
291 disable_icplb(); 252 _disable_icplb();
292 bfin_write32(ICPLB_DATA0 + idx * 4, i_data); 253 bfin_write32(ICPLB_DATA0 + idx * 4, i_data);
293 bfin_write32(ICPLB_ADDR0 + idx * 4, addr); 254 bfin_write32(ICPLB_ADDR0 + idx * 4, addr);
294 enable_icplb(); 255 _enable_icplb();
295 256
296 return 0; 257 return 0;
297} 258}
@@ -340,19 +301,19 @@ void flush_switched_cplbs(unsigned int cpu)
340 nr_cplb_flush[cpu]++; 301 nr_cplb_flush[cpu]++;
341 302
342 local_irq_save_hw(flags); 303 local_irq_save_hw(flags);
343 disable_icplb(); 304 _disable_icplb();
344 for (i = first_switched_icplb; i < MAX_CPLBS; i++) { 305 for (i = first_switched_icplb; i < MAX_CPLBS; i++) {
345 icplb_tbl[cpu][i].data = 0; 306 icplb_tbl[cpu][i].data = 0;
346 bfin_write32(ICPLB_DATA0 + i * 4, 0); 307 bfin_write32(ICPLB_DATA0 + i * 4, 0);
347 } 308 }
348 enable_icplb(); 309 _enable_icplb();
349 310
350 disable_dcplb(); 311 _disable_dcplb();
351 for (i = first_switched_dcplb; i < MAX_CPLBS; i++) { 312 for (i = first_switched_dcplb; i < MAX_CPLBS; i++) {
352 dcplb_tbl[cpu][i].data = 0; 313 dcplb_tbl[cpu][i].data = 0;
353 bfin_write32(DCPLB_DATA0 + i * 4, 0); 314 bfin_write32(DCPLB_DATA0 + i * 4, 0);
354 } 315 }
355 enable_dcplb(); 316 _enable_dcplb();
356 local_irq_restore_hw(flags); 317 local_irq_restore_hw(flags);
357 318
358} 319}
@@ -385,7 +346,7 @@ void set_mask_dcplbs(unsigned long *masks, unsigned int cpu)
385#endif 346#endif
386 } 347 }
387 348
388 disable_dcplb(); 349 _disable_dcplb();
389 for (i = first_mask_dcplb; i < first_switched_dcplb; i++) { 350 for (i = first_mask_dcplb; i < first_switched_dcplb; i++) {
390 dcplb_tbl[cpu][i].addr = addr; 351 dcplb_tbl[cpu][i].addr = addr;
391 dcplb_tbl[cpu][i].data = d_data; 352 dcplb_tbl[cpu][i].data = d_data;
@@ -393,6 +354,6 @@ void set_mask_dcplbs(unsigned long *masks, unsigned int cpu)
393 bfin_write32(DCPLB_ADDR0 + i * 4, addr); 354 bfin_write32(DCPLB_ADDR0 + i * 4, addr);
394 addr += PAGE_SIZE; 355 addr += PAGE_SIZE;
395 } 356 }
396 enable_dcplb(); 357 _enable_dcplb();
397 local_irq_restore_hw(flags); 358 local_irq_restore_hw(flags);
398} 359}
diff --git a/arch/blackfin/kernel/cplb-nompu/cacheinit.c b/arch/blackfin/kernel/cplb-nompu/cacheinit.c
index d5a86c3017f7..a082681faa8e 100644
--- a/arch/blackfin/kernel/cplb-nompu/cacheinit.c
+++ b/arch/blackfin/kernel/cplb-nompu/cacheinit.c
@@ -30,13 +30,14 @@ void __cpuinit bfin_icache_init(struct cplb_entry *icplb_tbl)
30 unsigned long ctrl; 30 unsigned long ctrl;
31 int i; 31 int i;
32 32
33 SSYNC();
34 for (i = 0; i < MAX_CPLBS; i++) { 33 for (i = 0; i < MAX_CPLBS; i++) {
35 bfin_write32(ICPLB_ADDR0 + i * 4, icplb_tbl[i].addr); 34 bfin_write32(ICPLB_ADDR0 + i * 4, icplb_tbl[i].addr);
36 bfin_write32(ICPLB_DATA0 + i * 4, icplb_tbl[i].data); 35 bfin_write32(ICPLB_DATA0 + i * 4, icplb_tbl[i].data);
37 } 36 }
38 ctrl = bfin_read_IMEM_CONTROL(); 37 ctrl = bfin_read_IMEM_CONTROL();
39 ctrl |= IMC | ENICPLB; 38 ctrl |= IMC | ENICPLB;
39 /* CSYNC to ensure load store ordering */
40 CSYNC();
40 bfin_write_IMEM_CONTROL(ctrl); 41 bfin_write_IMEM_CONTROL(ctrl);
41 SSYNC(); 42 SSYNC();
42} 43}
@@ -48,7 +49,6 @@ void __cpuinit bfin_dcache_init(struct cplb_entry *dcplb_tbl)
48 unsigned long ctrl; 49 unsigned long ctrl;
49 int i; 50 int i;
50 51
51 SSYNC();
52 for (i = 0; i < MAX_CPLBS; i++) { 52 for (i = 0; i < MAX_CPLBS; i++) {
53 bfin_write32(DCPLB_ADDR0 + i * 4, dcplb_tbl[i].addr); 53 bfin_write32(DCPLB_ADDR0 + i * 4, dcplb_tbl[i].addr);
54 bfin_write32(DCPLB_DATA0 + i * 4, dcplb_tbl[i].data); 54 bfin_write32(DCPLB_DATA0 + i * 4, dcplb_tbl[i].data);
@@ -63,6 +63,8 @@ void __cpuinit bfin_dcache_init(struct cplb_entry *dcplb_tbl)
63 * to port B 63 * to port B
64 */ 64 */
65 ctrl |= DMEM_CNTR | PORT_PREF0 | (ANOMALY_05000287 ? PORT_PREF1 : 0); 65 ctrl |= DMEM_CNTR | PORT_PREF0 | (ANOMALY_05000287 ? PORT_PREF1 : 0);
66 /* CSYNC to ensure load store ordering */
67 CSYNC();
66 bfin_write_DMEM_CONTROL(ctrl); 68 bfin_write_DMEM_CONTROL(ctrl);
67 SSYNC(); 69 SSYNC();
68} 70}
diff --git a/arch/blackfin/kernel/cplb-nompu/cplbmgr.c b/arch/blackfin/kernel/cplb-nompu/cplbmgr.c
index 12b030842fdb..aabbb42c42c4 100644
--- a/arch/blackfin/kernel/cplb-nompu/cplbmgr.c
+++ b/arch/blackfin/kernel/cplb-nompu/cplbmgr.c
@@ -48,36 +48,13 @@ int nr_cplb_flush[NR_CPUS], nr_dcplb_prot[NR_CPUS];
48#define MGR_ATTR 48#define MGR_ATTR
49#endif 49#endif
50 50
51/*
52 * We're in an exception handler. The normal cli nop nop workaround
53 * isn't going to do very much, as the only thing that can interrupt
54 * us is an NMI, and the cli isn't going to stop that.
55 */
56#define NOWA_SSYNC __asm__ __volatile__ ("ssync;")
57
58/* Anomaly handlers provide SSYNCs, so avoid extra if anomaly is present */
59#if ANOMALY_05000125
60
61#define bfin_write_DMEM_CONTROL_SSYNC(v) bfin_write_DMEM_CONTROL(v)
62#define bfin_write_IMEM_CONTROL_SSYNC(v) bfin_write_IMEM_CONTROL(v)
63
64#else
65
66#define bfin_write_DMEM_CONTROL_SSYNC(v) \
67 do { NOWA_SSYNC; bfin_write_DMEM_CONTROL(v); NOWA_SSYNC; } while (0)
68#define bfin_write_IMEM_CONTROL_SSYNC(v) \
69 do { NOWA_SSYNC; bfin_write_IMEM_CONTROL(v); NOWA_SSYNC; } while (0)
70
71#endif
72
73static inline void write_dcplb_data(int cpu, int idx, unsigned long data, 51static inline void write_dcplb_data(int cpu, int idx, unsigned long data,
74 unsigned long addr) 52 unsigned long addr)
75{ 53{
76 unsigned long ctrl = bfin_read_DMEM_CONTROL(); 54 _disable_dcplb();
77 bfin_write_DMEM_CONTROL_SSYNC(ctrl & ~ENDCPLB);
78 bfin_write32(DCPLB_DATA0 + idx * 4, data); 55 bfin_write32(DCPLB_DATA0 + idx * 4, data);
79 bfin_write32(DCPLB_ADDR0 + idx * 4, addr); 56 bfin_write32(DCPLB_ADDR0 + idx * 4, addr);
80 bfin_write_DMEM_CONTROL_SSYNC(ctrl); 57 _enable_dcplb();
81 58
82#ifdef CONFIG_CPLB_INFO 59#ifdef CONFIG_CPLB_INFO
83 dcplb_tbl[cpu][idx].addr = addr; 60 dcplb_tbl[cpu][idx].addr = addr;
@@ -88,12 +65,10 @@ static inline void write_dcplb_data(int cpu, int idx, unsigned long data,
88static inline void write_icplb_data(int cpu, int idx, unsigned long data, 65static inline void write_icplb_data(int cpu, int idx, unsigned long data,
89 unsigned long addr) 66 unsigned long addr)
90{ 67{
91 unsigned long ctrl = bfin_read_IMEM_CONTROL(); 68 _disable_icplb();
92
93 bfin_write_IMEM_CONTROL_SSYNC(ctrl & ~ENICPLB);
94 bfin_write32(ICPLB_DATA0 + idx * 4, data); 69 bfin_write32(ICPLB_DATA0 + idx * 4, data);
95 bfin_write32(ICPLB_ADDR0 + idx * 4, addr); 70 bfin_write32(ICPLB_ADDR0 + idx * 4, addr);
96 bfin_write_IMEM_CONTROL_SSYNC(ctrl); 71 _enable_icplb();
97 72
98#ifdef CONFIG_CPLB_INFO 73#ifdef CONFIG_CPLB_INFO
99 icplb_tbl[cpu][idx].addr = addr; 74 icplb_tbl[cpu][idx].addr = addr;
diff --git a/arch/blackfin/mach-bf561/secondary.S b/arch/blackfin/mach-bf561/secondary.S
index 097550f7b558..f72a6af20c4f 100644
--- a/arch/blackfin/mach-bf561/secondary.S
+++ b/arch/blackfin/mach-bf561/secondary.S
@@ -85,16 +85,10 @@ ENTRY(_coreb_trampoline_start)
85 R0 = ~ENICPLB; 85 R0 = ~ENICPLB;
86 R0 = R0 & R1; 86 R0 = R0 & R1;
87 87
88 /* Anomaly 05000125 */ 88 /* Disabling of CPLBs should be proceeded by a CSYNC */
89#ifdef ANOMALY_05000125 89 CSYNC;
90 CLI R2;
91 SSYNC;
92#endif
93 [p0] = R0; 90 [p0] = R0;
94 SSYNC; 91 SSYNC;
95#ifdef ANOMALY_05000125
96 STI R2;
97#endif
98 92
99 /* Turn off the dcache */ 93 /* Turn off the dcache */
100 p0.l = LO(DMEM_CONTROL); 94 p0.l = LO(DMEM_CONTROL);
@@ -103,16 +97,10 @@ ENTRY(_coreb_trampoline_start)
103 R0 = ~ENDCPLB; 97 R0 = ~ENDCPLB;
104 R0 = R0 & R1; 98 R0 = R0 & R1;
105 99
106 /* Anomaly 05000125 */ 100 /* Disabling of CPLBs should be proceeded by a CSYNC */
107#ifdef ANOMALY_05000125 101 CSYNC;
108 CLI R2;
109 SSYNC;
110#endif
111 [p0] = R0; 102 [p0] = R0;
112 SSYNC; 103 SSYNC;
113#ifdef ANOMALY_05000125
114 STI R2;
115#endif
116 104
117 /* in case of double faults, save a few things */ 105 /* in case of double faults, save a few things */
118 p0.l = _init_retx_coreb; 106 p0.l = _init_retx_coreb;
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S
index 4e8e3fe0ba1c..e7eb16355f74 100644
--- a/arch/blackfin/mach-common/entry.S
+++ b/arch/blackfin/mach-common/entry.S
@@ -397,8 +397,7 @@ ENTRY(_double_fault)
397 397
398 R5 = [P4]; /* Control Register*/ 398 R5 = [P4]; /* Control Register*/
399 BITCLR(R5,ENICPLB_P); 399 BITCLR(R5,ENICPLB_P);
400 SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */ 400 CSYNC; /* Disabling of CPLBs should be proceeded by a CSYNC */
401 .align 8;
402 [P4] = R5; 401 [P4] = R5;
403 SSYNC; 402 SSYNC;
404 403
@@ -406,8 +405,7 @@ ENTRY(_double_fault)
406 P4.H = HI(DMEM_CONTROL); 405 P4.H = HI(DMEM_CONTROL);
407 R5 = [P4]; 406 R5 = [P4];
408 BITCLR(R5,ENDCPLB_P); 407 BITCLR(R5,ENDCPLB_P);
409 SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */ 408 CSYNC; /* Disabling of CPLBs should be proceeded by a CSYNC */
410 .align 8;
411 [P4] = R5; 409 [P4] = R5;
412 SSYNC; 410 SSYNC;
413 411
@@ -1146,9 +1144,7 @@ ENTRY(_early_trap)
1146 1144
1147 R5 = [P4]; /* Control Register*/ 1145 R5 = [P4]; /* Control Register*/
1148 BITCLR(R5,ENICPLB_P); 1146 BITCLR(R5,ENICPLB_P);
1149 CLI R1; 1147 CSYNC; /* Disabling of CPLBs should be proceeded by a CSYNC */
1150 SSYNC; /* SSYNC required before writing to IMEM_CONTROL. */
1151 .align 8;
1152 [P4] = R5; 1148 [P4] = R5;
1153 SSYNC; 1149 SSYNC;
1154 1150
@@ -1156,11 +1152,9 @@ ENTRY(_early_trap)
1156 P4.H = HI(DMEM_CONTROL); 1152 P4.H = HI(DMEM_CONTROL);
1157 R5 = [P4]; 1153 R5 = [P4];
1158 BITCLR(R5,ENDCPLB_P); 1154 BITCLR(R5,ENDCPLB_P);
1159 SSYNC; /* SSYNC required before writing to DMEM_CONTROL. */ 1155 CSYNC; /* Disabling of CPLBs should be proceeded by a CSYNC */
1160 .align 8;
1161 [P4] = R5; 1156 [P4] = R5;
1162 SSYNC; 1157 SSYNC;
1163 STI R1;
1164 1158
1165 r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */ 1159 r0 = sp; /* stack frame pt_regs pointer argument ==> r0 */
1166 r1 = RETX; 1160 r1 = RETX;
diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c
index 9e7e27b7fc8d..0e3d4ff9d8b6 100644
--- a/arch/blackfin/mach-common/pm.c
+++ b/arch/blackfin/mach-common/pm.c
@@ -38,6 +38,7 @@
38#include <linux/io.h> 38#include <linux/io.h>
39#include <linux/irq.h> 39#include <linux/irq.h>
40 40
41#include <asm/cplb.h>
41#include <asm/gpio.h> 42#include <asm/gpio.h>
42#include <asm/dma.h> 43#include <asm/dma.h>
43#include <asm/dpmc.h> 44#include <asm/dpmc.h>
@@ -170,58 +171,6 @@ static void flushinv_all_dcache(void)
170} 171}
171#endif 172#endif
172 173
173static inline void dcache_disable(void)
174{
175#ifdef CONFIG_BFIN_DCACHE
176 unsigned long ctrl;
177
178#if defined(CONFIG_BFIN_EXTMEM_WRITEBACK) || defined(CONFIG_BFIN_L2_WRITEBACK)
179 flushinv_all_dcache();
180#endif
181 SSYNC();
182 ctrl = bfin_read_DMEM_CONTROL();
183 ctrl &= ~ENDCPLB;
184 bfin_write_DMEM_CONTROL(ctrl);
185 SSYNC();
186#endif
187}
188
189static inline void dcache_enable(void)
190{
191#ifdef CONFIG_BFIN_DCACHE
192 unsigned long ctrl;
193 SSYNC();
194 ctrl = bfin_read_DMEM_CONTROL();
195 ctrl |= ENDCPLB;
196 bfin_write_DMEM_CONTROL(ctrl);
197 SSYNC();
198#endif
199}
200
201static inline void icache_disable(void)
202{
203#ifdef CONFIG_BFIN_ICACHE
204 unsigned long ctrl;
205 SSYNC();
206 ctrl = bfin_read_IMEM_CONTROL();
207 ctrl &= ~ENICPLB;
208 bfin_write_IMEM_CONTROL(ctrl);
209 SSYNC();
210#endif
211}
212
213static inline void icache_enable(void)
214{
215#ifdef CONFIG_BFIN_ICACHE
216 unsigned long ctrl;
217 SSYNC();
218 ctrl = bfin_read_IMEM_CONTROL();
219 ctrl |= ENICPLB;
220 bfin_write_IMEM_CONTROL(ctrl);
221 SSYNC();
222#endif
223}
224
225int bfin_pm_suspend_mem_enter(void) 174int bfin_pm_suspend_mem_enter(void)
226{ 175{
227 unsigned long flags; 176 unsigned long flags;
@@ -258,16 +207,19 @@ int bfin_pm_suspend_mem_enter(void)
258 207
259 bfin_gpio_pm_hibernate_suspend(); 208 bfin_gpio_pm_hibernate_suspend();
260 209
261 dcache_disable(); 210#if defined(CONFIG_BFIN_EXTMEM_WRITEBACK) || defined(CONFIG_BFIN_L2_WRITEBACK)
262 icache_disable(); 211 flushinv_all_dcache();
212#endif
213 _disable_dcplb();
214 _disable_icplb();
263 bf53x_suspend_l1_mem(memptr); 215 bf53x_suspend_l1_mem(memptr);
264 216
265 do_hibernate(wakeup | vr_wakeup); /* Goodbye */ 217 do_hibernate(wakeup | vr_wakeup); /* Goodbye */
266 218
267 bf53x_resume_l1_mem(memptr); 219 bf53x_resume_l1_mem(memptr);
268 220
269 icache_enable(); 221 _enable_icplb();
270 dcache_enable(); 222 _enable_dcplb();
271 223
272 bfin_gpio_pm_hibernate_restore(); 224 bfin_gpio_pm_hibernate_restore();
273 blackfin_dma_resume(); 225 blackfin_dma_resume();