1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */ 2*4882a593Smuzhiyun #ifndef __ASM_POWERPC_CPU_HAS_FEATURE_H 3*4882a593Smuzhiyun #define __ASM_POWERPC_CPU_HAS_FEATURE_H 4*4882a593Smuzhiyun 5*4882a593Smuzhiyun #ifndef __ASSEMBLY__ 6*4882a593Smuzhiyun 7*4882a593Smuzhiyun #include <linux/bug.h> 8*4882a593Smuzhiyun #include <asm/cputable.h> 9*4882a593Smuzhiyun early_cpu_has_feature(unsigned long feature)10*4882a593Smuzhiyunstatic __always_inline bool early_cpu_has_feature(unsigned long feature) 11*4882a593Smuzhiyun { 12*4882a593Smuzhiyun return !!((CPU_FTRS_ALWAYS & feature) || 13*4882a593Smuzhiyun (CPU_FTRS_POSSIBLE & cur_cpu_spec->cpu_features & feature)); 14*4882a593Smuzhiyun } 15*4882a593Smuzhiyun 16*4882a593Smuzhiyun #ifdef CONFIG_JUMP_LABEL_FEATURE_CHECKS 17*4882a593Smuzhiyun #include <linux/jump_label.h> 18*4882a593Smuzhiyun 19*4882a593Smuzhiyun #define NUM_CPU_FTR_KEYS BITS_PER_LONG 20*4882a593Smuzhiyun 21*4882a593Smuzhiyun extern struct static_key_true cpu_feature_keys[NUM_CPU_FTR_KEYS]; 22*4882a593Smuzhiyun cpu_has_feature(unsigned long feature)23*4882a593Smuzhiyunstatic __always_inline bool cpu_has_feature(unsigned long feature) 24*4882a593Smuzhiyun { 25*4882a593Smuzhiyun int i; 26*4882a593Smuzhiyun 27*4882a593Smuzhiyun #ifndef __clang__ /* clang can't cope with this */ 28*4882a593Smuzhiyun BUILD_BUG_ON(!__builtin_constant_p(feature)); 29*4882a593Smuzhiyun #endif 30*4882a593Smuzhiyun 31*4882a593Smuzhiyun #ifdef CONFIG_JUMP_LABEL_FEATURE_CHECK_DEBUG 32*4882a593Smuzhiyun if (!static_key_initialized) { 33*4882a593Smuzhiyun printk("Warning! cpu_has_feature() used prior to jump label init!\n"); 34*4882a593Smuzhiyun dump_stack(); 35*4882a593Smuzhiyun return early_cpu_has_feature(feature); 36*4882a593Smuzhiyun } 37*4882a593Smuzhiyun #endif 38*4882a593Smuzhiyun 39*4882a593Smuzhiyun if (CPU_FTRS_ALWAYS & feature) 40*4882a593Smuzhiyun return true; 41*4882a593Smuzhiyun 42*4882a593Smuzhiyun if (!(CPU_FTRS_POSSIBLE & feature)) 43*4882a593Smuzhiyun return false; 44*4882a593Smuzhiyun 45*4882a593Smuzhiyun i = __builtin_ctzl(feature); 46*4882a593Smuzhiyun return static_branch_likely(&cpu_feature_keys[i]); 47*4882a593Smuzhiyun } 48*4882a593Smuzhiyun #else cpu_has_feature(unsigned long feature)49*4882a593Smuzhiyunstatic __always_inline bool cpu_has_feature(unsigned long feature) 50*4882a593Smuzhiyun { 51*4882a593Smuzhiyun return early_cpu_has_feature(feature); 52*4882a593Smuzhiyun } 53*4882a593Smuzhiyun #endif 54*4882a593Smuzhiyun 55*4882a593Smuzhiyun #endif /* __ASSEMBLY__ */ 56*4882a593Smuzhiyun #endif /* __ASM_POWERPC_CPU_HAS_FEATURE_H */ 57