1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2018, The Linux Foundation. All rights reserved.
3 
4 #include <linux/spinlock.h>
5 #include <linux/export.h>
6 
7 #include <asm/barrier.h>
8 #include <asm/krait-l2-accessors.h>
9 
10 static DEFINE_RAW_SPINLOCK(krait_l2_lock);
11 
12 void krait_set_l2_indirect_reg(u32 addr, u32 val)
13 {
14 	unsigned long flags;
15 
16 	raw_spin_lock_irqsave(&krait_l2_lock, flags);
17 	/*
18 	 * Select the L2 window by poking l2cpselr, then write to the window
19 	 * via l2cpdr.
20 	 */
21 	asm volatile ("mcr p15, 3, %0, c15, c0, 6 @ l2cpselr" : : "r" (addr));
22 	isb();
23 	asm volatile ("mcr p15, 3, %0, c15, c0, 7 @ l2cpdr" : : "r" (val));
24 	isb();
25 
26 	raw_spin_unlock_irqrestore(&krait_l2_lock, flags);
27 }
28 EXPORT_SYMBOL(krait_set_l2_indirect_reg);
29 
30 u32 krait_get_l2_indirect_reg(u32 addr)
31 {
32 	u32 val;
33 	unsigned long flags;
34 
35 	raw_spin_lock_irqsave(&krait_l2_lock, flags);
36 	/*
37 	 * Select the L2 window by poking l2cpselr, then read from the window
38 	 * via l2cpdr.
39 	 */
40 	asm volatile ("mcr p15, 3, %0, c15, c0, 6 @ l2cpselr" : : "r" (addr));
41 	isb();
42 	asm volatile ("mrc p15, 3, %0, c15, c0, 7 @ l2cpdr" : "=r" (val));
43 
44 	raw_spin_unlock_irqrestore(&krait_l2_lock, flags);
45 
46 	return val;
47 }
48 EXPORT_SYMBOL(krait_get_l2_indirect_reg);
49