summaryrefslogtreecommitdiff
path: root/arch/csky/mm/cachev2.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2020-04-06 09:55:50 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2020-04-06 09:55:50 -0700
commitf183d269cc6c64481b47ecbf9d3aff128dc0978c (patch)
tree3897411e0d277ac966c996c9acaf17f8252df027 /arch/csky/mm/cachev2.c
parentb6ff10700d1bf33c4323d34eca1e80bc8a69f9f5 (diff)
parentaefd9461d34a1b0a2acad0750c43216c1c27b9d4 (diff)
Merge tag 'csky-for-linus-5.7-rc1' of git://github.com/c-sky/csky-linux
Pull csky updates from Guo Ren: - Add kproobes/uprobes support - Add lockdep, rseq, gcov support - Fixup init_fpu - Fixup ftrace_modify deadlock - Fixup speculative execution on IO area * tag 'csky-for-linus-5.7-rc1' of git://github.com/c-sky/csky-linux: csky: Fixup cpu speculative execution to IO area csky: Add uprobes support csky: Add kprobes supported csky: Enable LOCKDEP_SUPPORT csky: Enable the gcov function csky: Fixup get wrong psr value from phyical reg csky/ftrace: Fixup ftrace_modify_code deadlock without CPU_HAS_ICACHE_INS csky: Implement ftrace with regs csky: Add support for restartable sequence csky: Implement ptrace regs and stack API csky: Fixup init_fpu compile warning with __init
Diffstat (limited to 'arch/csky/mm/cachev2.c')
-rw-r--r--arch/csky/mm/cachev2.c45
1 files changed, 39 insertions, 6 deletions
diff --git a/arch/csky/mm/cachev2.c b/arch/csky/mm/cachev2.c
index bc419f8039d3..7a9664adce43 100644
--- a/arch/csky/mm/cachev2.c
+++ b/arch/csky/mm/cachev2.c
@@ -7,8 +7,12 @@
#include <asm/cache.h>
#include <asm/barrier.h>
+/* for L1-cache */
#define INS_CACHE (1 << 0)
+#define DATA_CACHE (1 << 1)
#define CACHE_INV (1 << 4)
+#define CACHE_CLR (1 << 5)
+#define CACHE_OMS (1 << 6)
void local_icache_inv_all(void *priv)
{
@@ -16,11 +20,6 @@ void local_icache_inv_all(void *priv)
sync_is();
}
-void icache_inv_all(void)
-{
- on_each_cpu(local_icache_inv_all, NULL, 1);
-}
-
#ifdef CONFIG_CPU_HAS_ICACHE_INS
void icache_inv_range(unsigned long start, unsigned long end)
{
@@ -31,9 +30,43 @@ void icache_inv_range(unsigned long start, unsigned long end)
sync_is();
}
#else
+struct cache_range {
+ unsigned long start;
+ unsigned long end;
+};
+
+static DEFINE_SPINLOCK(cache_lock);
+
+static inline void cache_op_line(unsigned long i, unsigned int val)
+{
+ mtcr("cr22", i);
+ mtcr("cr17", val);
+}
+
+void local_icache_inv_range(void *priv)
+{
+ struct cache_range *param = priv;
+ unsigned long i = param->start & ~(L1_CACHE_BYTES - 1);
+ unsigned long flags;
+
+ spin_lock_irqsave(&cache_lock, flags);
+
+ for (; i < param->end; i += L1_CACHE_BYTES)
+ cache_op_line(i, INS_CACHE | CACHE_INV | CACHE_OMS);
+
+ spin_unlock_irqrestore(&cache_lock, flags);
+
+ sync_is();
+}
+
void icache_inv_range(unsigned long start, unsigned long end)
{
- icache_inv_all();
+ struct cache_range param = { start, end };
+
+ if (irqs_disabled())
+ local_icache_inv_range(&param);
+ else
+ on_each_cpu(local_icache_inv_range, &param, 1);
}
#endif