summaryrefslogtreecommitdiff
path: root/arch/mips/include/asm/pgtable.h
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2015-08-31 16:25:22 +0200
committerTakashi Iwai <tiwai@suse.de>2015-08-31 16:25:22 +0200
commit08ceab9d875824f8b389530e830349d5d6c4e582 (patch)
tree4ced69544742b87cb369de553df505870be593e1 /arch/mips/include/asm/pgtable.h
parent22c103cd3dfadff340b3b639e477a3c161cb2104 (diff)
parent91931320cfbbcc1dd874c2d0aef62e7d90f07f70 (diff)
Merge tag 'asoc-v4.2-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Updates for v4.3 Not many updates to the core here, but an awful lot of driver updates this time round: - Factoring out of AC'97 reset code into the core - New drivers for Cirrus CS4349, GTM601, InvenSense ICS43432, Realtek RT298 and ST STI controllers. - Machine drivers for Rockchip systems with MAX98090 and RT5645 and RT5650. - Initial driver support for Intel Skylake devices. - A large number of cleanups for Lars-Peter Clausen and Axel Lin.
Diffstat (limited to 'arch/mips/include/asm/pgtable.h')
-rw-r--r--arch/mips/include/asm/pgtable.h31
1 files changed, 31 insertions, 0 deletions
diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
index 9d8106758142..ae8569475264 100644
--- a/arch/mips/include/asm/pgtable.h
+++ b/arch/mips/include/asm/pgtable.h
@@ -182,8 +182,39 @@ static inline void set_pte(pte_t *ptep, pte_t pteval)
* Make sure the buddy is global too (if it's !none,
* it better already be global)
*/
+#ifdef CONFIG_SMP
+ /*
+ * For SMP, multiple CPUs can race, so we need to do
+ * this atomically.
+ */
+#ifdef CONFIG_64BIT
+#define LL_INSN "lld"
+#define SC_INSN "scd"
+#else /* CONFIG_32BIT */
+#define LL_INSN "ll"
+#define SC_INSN "sc"
+#endif
+ unsigned long page_global = _PAGE_GLOBAL;
+ unsigned long tmp;
+
+ __asm__ __volatile__ (
+ " .set push\n"
+ " .set noreorder\n"
+ "1: " LL_INSN " %[tmp], %[buddy]\n"
+ " bnez %[tmp], 2f\n"
+ " or %[tmp], %[tmp], %[global]\n"
+ " " SC_INSN " %[tmp], %[buddy]\n"
+ " beqz %[tmp], 1b\n"
+ " nop\n"
+ "2:\n"
+ " .set pop"
+ : [buddy] "+m" (buddy->pte),
+ [tmp] "=&r" (tmp)
+ : [global] "r" (page_global));
+#else /* !CONFIG_SMP */
if (pte_none(*buddy))
pte_val(*buddy) = pte_val(*buddy) | _PAGE_GLOBAL;
+#endif /* CONFIG_SMP */
}
#endif
}