1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org> 4*4882a593Smuzhiyun */ 5*4882a593Smuzhiyun 6*4882a593Smuzhiyun #ifndef __LINUX_CPUFEATURE_H 7*4882a593Smuzhiyun #define __LINUX_CPUFEATURE_H 8*4882a593Smuzhiyun 9*4882a593Smuzhiyun #ifdef CONFIG_GENERIC_CPU_AUTOPROBE 10*4882a593Smuzhiyun 11*4882a593Smuzhiyun #include <linux/init.h> 12*4882a593Smuzhiyun #include <linux/mod_devicetable.h> 13*4882a593Smuzhiyun #include <asm/cpufeature.h> 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun /* 16*4882a593Smuzhiyun * Macros imported from <asm/cpufeature.h>: 17*4882a593Smuzhiyun * - cpu_feature(x) ordinal value of feature called 'x' 18*4882a593Smuzhiyun * - cpu_have_feature(u32 n) whether feature #n is available 19*4882a593Smuzhiyun * - MAX_CPU_FEATURES upper bound for feature ordinal values 20*4882a593Smuzhiyun * Optional: 21*4882a593Smuzhiyun * - CPU_FEATURE_TYPEFMT format string fragment for printing the cpu type 22*4882a593Smuzhiyun * - CPU_FEATURE_TYPEVAL set of values matching the format string above 23*4882a593Smuzhiyun */ 24*4882a593Smuzhiyun 25*4882a593Smuzhiyun #ifndef CPU_FEATURE_TYPEFMT 26*4882a593Smuzhiyun #define CPU_FEATURE_TYPEFMT "%s" 27*4882a593Smuzhiyun #endif 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun #ifndef CPU_FEATURE_TYPEVAL 30*4882a593Smuzhiyun #define CPU_FEATURE_TYPEVAL ELF_PLATFORM 31*4882a593Smuzhiyun #endif 32*4882a593Smuzhiyun 33*4882a593Smuzhiyun /* 34*4882a593Smuzhiyun * Use module_cpu_feature_match(feature, module_init_function) to 35*4882a593Smuzhiyun * declare that 36*4882a593Smuzhiyun * a) the module shall be probed upon discovery of CPU feature 'feature' 37*4882a593Smuzhiyun * (typically at boot time using udev) 38*4882a593Smuzhiyun * b) the module must not be loaded if CPU feature 'feature' is not present 39*4882a593Smuzhiyun * (not even by manual insmod). 40*4882a593Smuzhiyun * 41*4882a593Smuzhiyun * For a list of legal values for 'feature', please consult the file 42*4882a593Smuzhiyun * 'asm/cpufeature.h' of your favorite architecture. 43*4882a593Smuzhiyun */ 44*4882a593Smuzhiyun #define module_cpu_feature_match(x, __initfunc) \ 45*4882a593Smuzhiyun static struct cpu_feature const __maybe_unused cpu_feature_match_ ## x[] = \ 46*4882a593Smuzhiyun { { .feature = cpu_feature(x) }, { } }; \ 47*4882a593Smuzhiyun MODULE_DEVICE_TABLE(cpu, cpu_feature_match_ ## x); \ 48*4882a593Smuzhiyun \ 49*4882a593Smuzhiyun static int __init cpu_feature_match_ ## x ## _init(void) \ 50*4882a593Smuzhiyun { \ 51*4882a593Smuzhiyun if (!cpu_have_feature(cpu_feature(x))) \ 52*4882a593Smuzhiyun return -ENODEV; \ 53*4882a593Smuzhiyun return __initfunc(); \ 54*4882a593Smuzhiyun } \ 55*4882a593Smuzhiyun module_init(cpu_feature_match_ ## x ## _init) 56*4882a593Smuzhiyun 57*4882a593Smuzhiyun #endif 58*4882a593Smuzhiyun #endif 59