1156952Sume// SPDX-License-Identifier: GPL-2.0-only OR MIT 2156952Sume/* Copyright (c) 2023 Imagination Technologies Ltd. */ 3156952Sume 4156952Sume#include "pvr_params.h" 5156952Sume 6156952Sume#include <linux/cache.h> 7156952Sume#include <linux/moduleparam.h> 8156952Sume 9156952Sumestatic struct pvr_device_params pvr_device_param_defaults __read_mostly = { 10156952Sume#define X(type_, name_, value_, desc_, ...) .name_ = (value_), 11156952Sume PVR_DEVICE_PARAMS 12156952Sume#undef X 13156952Sume}; 14156952Sume 15156952Sume#define PVR_DEVICE_PARAM_NAMED(name_, type_, desc_) \ 16156952Sume module_param_named(name_, pvr_device_param_defaults.name_, type_, \ 17156952Sume 0400); \ 18156952Sume MODULE_PARM_DESC(name_, desc_); 19156952Sume 20156952Sume/* 21156952Sume * This list of defines must contain every type specified in "pvr_params.h" as 22156952Sume * ``PVR_PARAM_TYPE_*_C``. 23156952Sume */ 24156952Sume#define PVR_PARAM_TYPE_X32_MODPARAM uint 25156952Sume 26156952Sume#define X(type_, name_, value_, desc_, ...) \ 27156952Sume PVR_DEVICE_PARAM_NAMED(name_, PVR_PARAM_TYPE_##type_##_MODPARAM, desc_); 28156952SumePVR_DEVICE_PARAMS 29156952Sume#undef X 30156952Sume 31156952Sumeint 32156952Sumepvr_device_params_init(struct pvr_device_params *params) 33156952Sume{ 34156952Sume /* 35156952Sume * If heap-allocated parameters are added in the future (e.g. 36156952Sume * modparam's charp type), they must be handled specially here (via 37156952Sume * kstrdup() in the case of charp). Since that's not necessary yet, 38156952Sume * a straight copy will do for now. This change will also require a 39156952Sume * pvr_device_params_fini() function to free any heap-allocated copies. 40156952Sume */ 41156952Sume 42156952Sume *params = pvr_device_param_defaults; 43156952Sume 44156952Sume return 0; 45156952Sume} 46156952Sume 47156952Sume#if defined(CONFIG_DEBUG_FS) 48156952Sume#include "pvr_device.h" 49156952Sume 50156952Sume#include <linux/dcache.h> 51156952Sume#include <linux/debugfs.h> 52156952Sume#include <linux/export.h> 53156952Sume#include <linux/fs.h> 54156952Sume#include <linux/stddef.h> 55156952Sume 56156952Sume/* 57156952Sume * This list of defines must contain every type specified in "pvr_params.h" as 58156952Sume * ``PVR_PARAM_TYPE_*_C``. 59156952Sume */ 60156952Sume#define PVR_PARAM_TYPE_X32_FMT "0x%08llx" 61156952Sume 62156952Sume#define X_SET(name_, mode_) X_SET_##mode_(name_) 63156952Sume#define X_SET_DEF(name_, update_, mode_) X_SET_DEF_##mode_(name_, update_) 64156952Sume 65156952Sume#define X_SET_RO(name_) NULL 66156952Sume#define X_SET_RW(name_) __pvr_device_param_##name_##set 67156952Sume 68156952Sume#define X_SET_DEF_RO(name_, update_) 69270838Sume#define X_SET_DEF_RW(name_, update_) \ 70156952Sume static int \ 71156956Sume X_SET_RW(name_)(void *data, u64 val) \ 72156956Sume { \ 73156952Sume struct pvr_device *pvr_dev = data; \ 74156952Sume /* This is not just (update_) to suppress -Waddress. */ \ 75156952Sume if ((void *)(update_) != NULL) \ 76156952Sume (update_)(pvr_dev, pvr_dev->params.name_, val); \ 77156952Sume pvr_dev->params.name_ = val; \ 78156952Sume return 0; \ 79156952Sume } 80156952Sume 81156952Sume#define X(type_, name_, value_, desc_, mode_, update_) \ 82156952Sume static int \ 83156952Sume __pvr_device_param_##name_##_get(void *data, u64 *val) \ 84156952Sume { \ 85156952Sume struct pvr_device *pvr_dev = data; \ 86170244Sume *val = pvr_dev->params.name_; \ 87156952Sume return 0; \ 88170244Sume } \ 89170244Sume X_SET_DEF(name_, update_, mode_) \ 90170244Sume static int \ 91170244Sume __pvr_device_param_##name_##_open(struct inode *inode, \ 92170244Sume struct file *file) \ 93156952Sume { \ 94156952Sume __simple_attr_check_format(PVR_PARAM_TYPE_##type_##_FMT, \ 95156952Sume 0ull); \ 96156952Sume return simple_attr_open(inode, file, \ 97156952Sume __pvr_device_param_##name_##_get, \ 98156952Sume X_SET(name_, mode_), \ 99156952Sume PVR_PARAM_TYPE_##type_##_FMT); \ 100156952Sume } 101156952SumePVR_DEVICE_PARAMS 102156952Sume#undef X 103156952Sume 104156952Sume#undef X_SET 105170244Sume#undef X_SET_RO 106156952Sume#undef X_SET_RW 107170244Sume#undef X_SET_DEF 108170244Sume#undef X_SET_DEF_RO 109170244Sume#undef X_SET_DEF_RW 110156952Sume 111156952Sumestatic struct { 112156952Sume#define X(type_, name_, value_, desc_, mode_, update_) \ 113156952Sume const struct file_operations name_; 114156952Sume PVR_DEVICE_PARAMS 115156952Sume#undef X 116156952Sume} pvr_device_param_debugfs_fops = { 117156952Sume#define X(type_, name_, value_, desc_, mode_, update_) \ 118156952Sume .name_ = { \ 119156952Sume .owner = THIS_MODULE, \ 120170244Sume .open = __pvr_device_param_##name_##_open, \ 121156952Sume .release = simple_attr_release, \ 122156952Sume .read = simple_attr_read, \ 123156952Sume .write = simple_attr_write, \ 124156952Sume .llseek = generic_file_llseek, \ 125156952Sume }, 126156952Sume PVR_DEVICE_PARAMS 127156952Sume#undef X 128156952Sume}; 129156952Sume 130156952Sumevoid 131156952Sumepvr_params_debugfs_init(struct pvr_device *pvr_dev, struct dentry *dir) 132170244Sume{ 133156952Sume#define X_MODE(mode_) X_MODE_##mode_ 134170244Sume#define X_MODE_RO 0400 135156952Sume#define X_MODE_RW 0600 136156952Sume 137156952Sume#define X(type_, name_, value_, desc_, mode_, update_) \ 138156952Sume debugfs_create_file(#name_, X_MODE(mode_), dir, pvr_dev, \ 139156952Sume &pvr_device_param_debugfs_fops.name_); 140156952Sume PVR_DEVICE_PARAMS 141156952Sume#undef X 142156952Sume 143176325Sdelphij#undef X_MODE 144156952Sume#undef X_MODE_RO 145156952Sume#undef X_MODE_RW 146156952Sume} 147156952Sume#endif 148156952Sume