1 // SPDX-License-Identifier: GPL-2.0-only OR MIT 2 /* Copyright (c) 2023 Imagination Technologies Ltd. */ 3 4 #include "pvr_params.h" 5 6 #include <linux/cache.h> 7 #include <linux/moduleparam.h> 8 9 static struct pvr_device_params pvr_device_param_defaults __read_mostly = { 10 #define X(type_, name_, value_, desc_, ...) .name_ = (value_), 11 PVR_DEVICE_PARAMS 12 #undef X 13 }; 14 15 #define PVR_DEVICE_PARAM_NAMED(name_, type_, desc_) \ 16 module_param_named(name_, pvr_device_param_defaults.name_, type_, \ 17 0400); \ 18 MODULE_PARM_DESC(name_, desc_); 19 20 /* 21 * This list of defines must contain every type specified in "pvr_params.h" as 22 * ``PVR_PARAM_TYPE_*_C``. 23 */ 24 #define PVR_PARAM_TYPE_X32_MODPARAM uint 25 26 #define X(type_, name_, value_, desc_, ...) \ 27 PVR_DEVICE_PARAM_NAMED(name_, PVR_PARAM_TYPE_##type_##_MODPARAM, desc_); 28 PVR_DEVICE_PARAMS 29 #undef X 30 31 int 32 pvr_device_params_init(struct pvr_device_params *params) 33 { 34 /* 35 * If heap-allocated parameters are added in the future (e.g. 36 * modparam's charp type), they must be handled specially here (via 37 * kstrdup() in the case of charp). Since that's not necessary yet, 38 * a straight copy will do for now. This change will also require a 39 * pvr_device_params_fini() function to free any heap-allocated copies. 40 */ 41 42 *params = pvr_device_param_defaults; 43 44 return 0; 45 } 46 47 #if defined(CONFIG_DEBUG_FS) 48 #include "pvr_device.h" 49 50 #include <linux/dcache.h> 51 #include <linux/debugfs.h> 52 #include <linux/export.h> 53 #include <linux/fs.h> 54 #include <linux/stddef.h> 55 56 /* 57 * This list of defines must contain every type specified in "pvr_params.h" as 58 * ``PVR_PARAM_TYPE_*_C``. 59 */ 60 #define PVR_PARAM_TYPE_X32_FMT "0x%08llx" 61 62 #define X_SET(name_, mode_) X_SET_##mode_(name_) 63 #define X_SET_DEF(name_, update_, mode_) X_SET_DEF_##mode_(name_, update_) 64 65 #define X_SET_RO(name_) NULL 66 #define X_SET_RW(name_) __pvr_device_param_##name_##set 67 68 #define X_SET_DEF_RO(name_, update_) 69 #define X_SET_DEF_RW(name_, update_) \ 70 static int \ 71 X_SET_RW(name_)(void *data, u64 val) \ 72 { \ 73 struct pvr_device *pvr_dev = data; \ 74 /* This is not just (update_) to suppress -Waddress. */ \ 75 if ((void *)(update_) != NULL) \ 76 (update_)(pvr_dev, pvr_dev->params.name_, val); \ 77 pvr_dev->params.name_ = val; \ 78 return 0; \ 79 } 80 81 #define X(type_, name_, value_, desc_, mode_, update_) \ 82 static int \ 83 __pvr_device_param_##name_##_get(void *data, u64 *val) \ 84 { \ 85 struct pvr_device *pvr_dev = data; \ 86 *val = pvr_dev->params.name_; \ 87 return 0; \ 88 } \ 89 X_SET_DEF(name_, update_, mode_) \ 90 static int \ 91 __pvr_device_param_##name_##_open(struct inode *inode, \ 92 struct file *file) \ 93 { \ 94 __simple_attr_check_format(PVR_PARAM_TYPE_##type_##_FMT, \ 95 0ull); \ 96 return simple_attr_open(inode, file, \ 97 __pvr_device_param_##name_##_get, \ 98 X_SET(name_, mode_), \ 99 PVR_PARAM_TYPE_##type_##_FMT); \ 100 } 101 PVR_DEVICE_PARAMS 102 #undef X 103 104 #undef X_SET 105 #undef X_SET_RO 106 #undef X_SET_RW 107 #undef X_SET_DEF 108 #undef X_SET_DEF_RO 109 #undef X_SET_DEF_RW 110 111 static struct { 112 #define X(type_, name_, value_, desc_, mode_, update_) \ 113 const struct file_operations name_; 114 PVR_DEVICE_PARAMS 115 #undef X 116 } pvr_device_param_debugfs_fops = { 117 #define X(type_, name_, value_, desc_, mode_, update_) \ 118 .name_ = { \ 119 .owner = THIS_MODULE, \ 120 .open = __pvr_device_param_##name_##_open, \ 121 .release = simple_attr_release, \ 122 .read = simple_attr_read, \ 123 .write = simple_attr_write, \ 124 .llseek = generic_file_llseek, \ 125 }, 126 PVR_DEVICE_PARAMS 127 #undef X 128 }; 129 130 void 131 pvr_params_debugfs_init(struct pvr_device *pvr_dev, struct dentry *dir) 132 { 133 #define X_MODE(mode_) X_MODE_##mode_ 134 #define X_MODE_RO 0400 135 #define X_MODE_RW 0600 136 137 #define X(type_, name_, value_, desc_, mode_, update_) \ 138 debugfs_create_file(#name_, X_MODE(mode_), dir, pvr_dev, \ 139 &pvr_device_param_debugfs_fops.name_); 140 PVR_DEVICE_PARAMS 141 #undef X 142 143 #undef X_MODE 144 #undef X_MODE_RO 145 #undef X_MODE_RW 146 } 147 #endif 148