18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef __ASM_POWERPC_CPU_HAS_FEATURE_H 38c2ecf20Sopenharmony_ci#define __ASM_POWERPC_CPU_HAS_FEATURE_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include <linux/bug.h> 88c2ecf20Sopenharmony_ci#include <asm/cputable.h> 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_cistatic __always_inline bool early_cpu_has_feature(unsigned long feature) 118c2ecf20Sopenharmony_ci{ 128c2ecf20Sopenharmony_ci return !!((CPU_FTRS_ALWAYS & feature) || 138c2ecf20Sopenharmony_ci (CPU_FTRS_POSSIBLE & cur_cpu_spec->cpu_features & feature)); 148c2ecf20Sopenharmony_ci} 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#ifdef CONFIG_JUMP_LABEL_FEATURE_CHECKS 178c2ecf20Sopenharmony_ci#include <linux/jump_label.h> 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci#define NUM_CPU_FTR_KEYS BITS_PER_LONG 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ciextern struct static_key_true cpu_feature_keys[NUM_CPU_FTR_KEYS]; 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_cistatic __always_inline bool cpu_has_feature(unsigned long feature) 248c2ecf20Sopenharmony_ci{ 258c2ecf20Sopenharmony_ci int i; 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci#ifndef __clang__ /* clang can't cope with this */ 288c2ecf20Sopenharmony_ci BUILD_BUG_ON(!__builtin_constant_p(feature)); 298c2ecf20Sopenharmony_ci#endif 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci#ifdef CONFIG_JUMP_LABEL_FEATURE_CHECK_DEBUG 328c2ecf20Sopenharmony_ci if (!static_key_initialized) { 338c2ecf20Sopenharmony_ci printk("Warning! cpu_has_feature() used prior to jump label init!\n"); 348c2ecf20Sopenharmony_ci dump_stack(); 358c2ecf20Sopenharmony_ci return early_cpu_has_feature(feature); 368c2ecf20Sopenharmony_ci } 378c2ecf20Sopenharmony_ci#endif 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci if (CPU_FTRS_ALWAYS & feature) 408c2ecf20Sopenharmony_ci return true; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci if (!(CPU_FTRS_POSSIBLE & feature)) 438c2ecf20Sopenharmony_ci return false; 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci i = __builtin_ctzl(feature); 468c2ecf20Sopenharmony_ci return static_branch_likely(&cpu_feature_keys[i]); 478c2ecf20Sopenharmony_ci} 488c2ecf20Sopenharmony_ci#else 498c2ecf20Sopenharmony_cistatic __always_inline bool cpu_has_feature(unsigned long feature) 508c2ecf20Sopenharmony_ci{ 518c2ecf20Sopenharmony_ci return early_cpu_has_feature(feature); 528c2ecf20Sopenharmony_ci} 538c2ecf20Sopenharmony_ci#endif 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci#endif /* __ASSEMBLY__ */ 568c2ecf20Sopenharmony_ci#endif /* __ASM_POWERPC_CPU_HAS_FEATURE_H */ 57