aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
diff options
context:
space:
mode:
authorYi Li <yi.li@analog.com>2009-08-06 21:20:58 -0400
committerMike Frysinger <vapier@gentoo.org>2009-09-16 22:10:19 -0400
commiteb7bd9c461bbfbb195cb1e1346453222a4352df4 (patch)
tree9c92f6ce5160b655213bbcff8175878771594121 /arch/blackfin/kernel/cplb-mpu/cplbmgr.c
parent8312440e05ea74feabc648ad8f36c823af4ddd8e (diff)
Blackfin: cleanup sync handling when enabling/disabling cplbs
The handling of updating the [DI]MEM_CONTROL MMRs does not follow proper sync procedures as laid out in the Blackfin programming manual. So rather than audit/fix every call location, create helper functions that do the right things in order to safely update these MMRs. Then convert all call sites to use these new helper functions. While we're fixing the code, drop the workaround for anomaly 05000125 as that anomaly applies to old versions of silicon that we do not support. Signed-off-by: Yi Li <yi.li@analog.com> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'arch/blackfin/kernel/cplb-mpu/cplbmgr.c')
-rw-r--r--arch/blackfin/kernel/cplb-mpu/cplbmgr.c61
1 files changed, 11 insertions, 50 deletions
diff --git a/arch/blackfin/kernel/cplb-mpu/cplbmgr.c b/arch/blackfin/kernel/cplb-mpu/cplbmgr.c
index bcdfe9b0b71..651b12773e0 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}