aboutsummaryrefslogtreecommitdiffstats
path: root/arch/blackfin/kernel/cplb-nompu/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-nompu/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-nompu/cplbmgr.c')
-rw-r--r--arch/blackfin/kernel/cplb-nompu/cplbmgr.c33
1 files changed, 4 insertions, 29 deletions
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;