18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef __ASM_LSE_H 38c2ecf20Sopenharmony_ci#define __ASM_LSE_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#include <asm/atomic_ll_sc.h> 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#ifdef CONFIG_ARM64_LSE_ATOMICS 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#define __LSE_PREAMBLE ".arch_extension lse\n" 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include <linux/compiler_types.h> 128c2ecf20Sopenharmony_ci#include <linux/export.h> 138c2ecf20Sopenharmony_ci#include <linux/jump_label.h> 148c2ecf20Sopenharmony_ci#include <linux/stringify.h> 158c2ecf20Sopenharmony_ci#include <asm/alternative.h> 168c2ecf20Sopenharmony_ci#include <asm/atomic_lse.h> 178c2ecf20Sopenharmony_ci#include <asm/cpucaps.h> 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ciextern struct static_key_false cpu_hwcap_keys[ARM64_NCAPS]; 208c2ecf20Sopenharmony_ciextern struct static_key_false arm64_const_caps_ready; 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_cistatic inline bool system_uses_lse_atomics(void) 238c2ecf20Sopenharmony_ci{ 248c2ecf20Sopenharmony_ci return (static_branch_likely(&arm64_const_caps_ready)) && 258c2ecf20Sopenharmony_ci static_branch_likely(&cpu_hwcap_keys[ARM64_HAS_LSE_ATOMICS]); 268c2ecf20Sopenharmony_ci} 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci#define __lse_ll_sc_body(op, ...) \ 298c2ecf20Sopenharmony_ci({ \ 308c2ecf20Sopenharmony_ci system_uses_lse_atomics() ? \ 318c2ecf20Sopenharmony_ci __lse_##op(__VA_ARGS__) : \ 328c2ecf20Sopenharmony_ci __ll_sc_##op(__VA_ARGS__); \ 338c2ecf20Sopenharmony_ci}) 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci/* In-line patching at runtime */ 368c2ecf20Sopenharmony_ci#define ARM64_LSE_ATOMIC_INSN(llsc, lse) \ 378c2ecf20Sopenharmony_ci ALTERNATIVE(llsc, __LSE_PREAMBLE lse, ARM64_HAS_LSE_ATOMICS) 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci#else /* CONFIG_ARM64_LSE_ATOMICS */ 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_cistatic inline bool system_uses_lse_atomics(void) { return false; } 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci#define __lse_ll_sc_body(op, ...) __ll_sc_##op(__VA_ARGS__) 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci#define ARM64_LSE_ATOMIC_INSN(llsc, lse) llsc 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci#endif /* CONFIG_ARM64_LSE_ATOMICS */ 488c2ecf20Sopenharmony_ci#endif /* __ASM_LSE_H */ 49