162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#ifndef __ASM_POWERPC_CPU_HAS_FEATURE_H 362306a36Sopenharmony_ci#define __ASM_POWERPC_CPU_HAS_FEATURE_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#ifndef __ASSEMBLY__ 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#include <linux/bug.h> 862306a36Sopenharmony_ci#include <asm/cputable.h> 962306a36Sopenharmony_ci 1062306a36Sopenharmony_cistatic __always_inline bool early_cpu_has_feature(unsigned long feature) 1162306a36Sopenharmony_ci{ 1262306a36Sopenharmony_ci return !!((CPU_FTRS_ALWAYS & feature) || 1362306a36Sopenharmony_ci (CPU_FTRS_POSSIBLE & cur_cpu_spec->cpu_features & feature)); 1462306a36Sopenharmony_ci} 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#ifdef CONFIG_JUMP_LABEL_FEATURE_CHECKS 1762306a36Sopenharmony_ci#include <linux/jump_label.h> 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#define NUM_CPU_FTR_KEYS BITS_PER_LONG 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ciextern struct static_key_true cpu_feature_keys[NUM_CPU_FTR_KEYS]; 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_cistatic __always_inline bool cpu_has_feature(unsigned long feature) 2462306a36Sopenharmony_ci{ 2562306a36Sopenharmony_ci int i; 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci#ifndef __clang__ /* clang can't cope with this */ 2862306a36Sopenharmony_ci BUILD_BUG_ON(!__builtin_constant_p(feature)); 2962306a36Sopenharmony_ci#endif 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci#ifdef CONFIG_JUMP_LABEL_FEATURE_CHECK_DEBUG 3262306a36Sopenharmony_ci if (!static_key_initialized) { 3362306a36Sopenharmony_ci printk("Warning! cpu_has_feature() used prior to jump label init!\n"); 3462306a36Sopenharmony_ci dump_stack(); 3562306a36Sopenharmony_ci return early_cpu_has_feature(feature); 3662306a36Sopenharmony_ci } 3762306a36Sopenharmony_ci#endif 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci if (CPU_FTRS_ALWAYS & feature) 4062306a36Sopenharmony_ci return true; 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci if (!(CPU_FTRS_POSSIBLE & feature)) 4362306a36Sopenharmony_ci return false; 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci i = __builtin_ctzl(feature); 4662306a36Sopenharmony_ci return static_branch_likely(&cpu_feature_keys[i]); 4762306a36Sopenharmony_ci} 4862306a36Sopenharmony_ci#else 4962306a36Sopenharmony_cistatic __always_inline bool cpu_has_feature(unsigned long feature) 5062306a36Sopenharmony_ci{ 5162306a36Sopenharmony_ci return early_cpu_has_feature(feature); 5262306a36Sopenharmony_ci} 5362306a36Sopenharmony_ci#endif 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci#endif /* __ASSEMBLY__ */ 5662306a36Sopenharmony_ci#endif /* __ASM_POWERPC_CPU_HAS_FEATURE_H */ 57