Loading...
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
9static 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_);
28PVR_DEVICE_PARAMS
29#undef X
30
31int
32pvr_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 }
101PVR_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
111static 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
130void
131pvr_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