diff options
| author | Mike Frysinger <vapier@gentoo.org> | 2009-11-02 22:14:38 -0500 |
|---|---|---|
| committer | Mike Frysinger <vapier@gentoo.org> | 2009-11-25 02:35:39 -0500 |
| commit | f99e8c1d0f41011870d14d5990c65e65b123f2ef (patch) | |
| tree | 6b35870bf38310d700d2349792775f8634cb261f | |
| parent | af5d7fc7e4d8e34bad42178f7011287e94eeb3ed (diff) | |
Blackfin: work around testset anomaly 05000477
Ironically, the atomic testset instruction cannot be interrupted else it
will produce incorrect results. So disable interrupts to help it out.
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
| -rw-r--r-- | arch/blackfin/mach-bf561/atomic.S | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/arch/blackfin/mach-bf561/atomic.S b/arch/blackfin/mach-bf561/atomic.S index 0261a5e751b3..f99f174b129f 100644 --- a/arch/blackfin/mach-bf561/atomic.S +++ b/arch/blackfin/mach-bf561/atomic.S | |||
| @@ -19,6 +19,16 @@ | |||
| 19 | \reg\().h = _corelock; | 19 | \reg\().h = _corelock; |
| 20 | .endm | 20 | .endm |
| 21 | 21 | ||
| 22 | .macro safe_testset addr:req, scratch:req | ||
| 23 | #if ANOMALY_05000477 | ||
| 24 | cli \scratch; | ||
| 25 | testset (\addr); | ||
| 26 | sti \scratch; | ||
| 27 | #else | ||
| 28 | testset (\addr); | ||
| 29 | #endif | ||
| 30 | .endm | ||
| 31 | |||
| 22 | /* | 32 | /* |
| 23 | * r0 = address of atomic data to flush and invalidate (32bit). | 33 | * r0 = address of atomic data to flush and invalidate (32bit). |
| 24 | * | 34 | * |
| @@ -33,7 +43,7 @@ ENTRY(_get_core_lock) | |||
| 33 | cli r0; | 43 | cli r0; |
| 34 | coreslot_loadaddr p0; | 44 | coreslot_loadaddr p0; |
| 35 | .Lretry_corelock: | 45 | .Lretry_corelock: |
| 36 | testset (p0); | 46 | safe_testset p0, r2; |
| 37 | if cc jump .Ldone_corelock; | 47 | if cc jump .Ldone_corelock; |
| 38 | SSYNC(r2); | 48 | SSYNC(r2); |
| 39 | jump .Lretry_corelock | 49 | jump .Lretry_corelock |
| @@ -56,7 +66,7 @@ ENTRY(_get_core_lock_noflush) | |||
| 56 | cli r0; | 66 | cli r0; |
| 57 | coreslot_loadaddr p0; | 67 | coreslot_loadaddr p0; |
| 58 | .Lretry_corelock_noflush: | 68 | .Lretry_corelock_noflush: |
| 59 | testset (p0); | 69 | safe_testset p0, r2; |
| 60 | if cc jump .Ldone_corelock_noflush; | 70 | if cc jump .Ldone_corelock_noflush; |
| 61 | SSYNC(r2); | 71 | SSYNC(r2); |
| 62 | jump .Lretry_corelock_noflush | 72 | jump .Lretry_corelock_noflush |
