GNU Linux-libre 4.19.264-gnu1
[releases.git] / drivers / staging / gasket / gasket_sysfs.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Set of common sysfs utilities.
4  *
5  * Copyright (C) 2018 Google, Inc.
6  */
7
8 /* The functions described here are a set of utilities to allow each file in the
9  * Gasket driver framework to manage their own set of sysfs entries, instead of
10  * centralizing all that work in one file.
11  *
12  * The goal of these utilities is to allow for sysfs entries to be easily
13  * created without causing a proliferation of sysfs "show" functions. This
14  * requires O(N) string lookups during show function execution, but as reading
15  * sysfs entries is rarely performance-critical, this is likely acceptible.
16  */
17 #ifndef __GASKET_SYSFS_H__
18 #define __GASKET_SYSFS_H__
19
20 #include "gasket_constants.h"
21 #include "gasket_core.h"
22 #include <linux/device.h>
23 #include <linux/stringify.h>
24 #include <linux/sysfs.h>
25
26 /* The maximum number of mappings/devices a driver needs to support. */
27 #define GASKET_SYSFS_NUM_MAPPINGS (GASKET_FRAMEWORK_DESC_MAX * GASKET_DEV_MAX)
28
29 /* The maximum number of sysfs nodes in a directory.
30  */
31 #define GASKET_SYSFS_MAX_NODES 196
32
33 /* End markers for sysfs struct arrays. */
34 #define GASKET_ARRAY_END_TOKEN GASKET_RESERVED_ARRAY_END
35 #define GASKET_ARRAY_END_MARKER __stringify(GASKET_ARRAY_END_TOKEN)
36
37 /*
38  * Terminator struct for a gasket_sysfs_attr array. Must be at the end of
39  * all gasket_sysfs_attribute arrays.
40  */
41 #define GASKET_END_OF_ATTR_ARRAY                                               \
42         {                                                                      \
43                 .attr = __ATTR(GASKET_ARRAY_END_TOKEN, S_IRUGO, NULL, NULL),   \
44                 .data.attr_type = 0,                                           \
45         }
46
47 /*
48  * Pairing of sysfs attribute and user data.
49  * Used in lookups in sysfs "show" functions to return attribute metadata.
50  */
51 struct gasket_sysfs_attribute {
52         /* The underlying sysfs device attribute associated with this data. */
53         struct device_attribute attr;
54
55         /* User-specified data to associate with the attribute. */
56         union {
57                 struct bar_address_ {
58                         ulong bar;
59                         ulong offset;
60                 } bar_address;
61                 uint attr_type;
62         } data;
63
64         /*
65          * Function pointer to a callback to be invoked when this attribute is
66          * written (if so configured). The arguments are to the Gasket device
67          * pointer, the enclosing gasket_attr structure, and the value written.
68          * The callback should perform any logging necessary, as errors cannot
69          * be returned from the callback.
70          */
71         void (*write_callback)(struct gasket_dev *dev,
72                                struct gasket_sysfs_attribute *attr,
73                                ulong value);
74 };
75
76 #define GASKET_SYSFS_RO(_name, _show_function, _attr_type)                     \
77         {                                                                      \
78                 .attr = __ATTR(_name, S_IRUGO, _show_function, NULL),          \
79                 .data.attr_type = _attr_type                                   \
80         }
81
82 /* Initializes the Gasket sysfs subsystem.
83  *
84  * Description: Performs one-time initialization. Must be called before usage
85  * at [Gasket] module load time.
86  */
87 void gasket_sysfs_init(void);
88
89 /*
90  * Create an entry in mapping_data between a device and a Gasket device.
91  * @device: Device struct to map to.
92  * @gasket_dev: The dev struct associated with the driver controlling @device.
93  *
94  * Description: This function maps a gasket_dev* to a device*. This mapping can
95  * be used in sysfs_show functions to get a handle to the gasket_dev struct
96  * controlling the device node.
97  *
98  * If this function is not called before gasket_sysfs_create_entries, a warning
99  * will be logged.
100  */
101 int gasket_sysfs_create_mapping(struct device *device,
102                                 struct gasket_dev *gasket_dev);
103
104 /*
105  * Creates bulk entries in sysfs.
106  * @device: Kernel device structure.
107  * @attrs: List of attributes/sysfs entries to create.
108  *
109  * Description: Creates each sysfs entry described in "attrs". Can be called
110  * multiple times for a given @device. If the gasket_dev specified in
111  * gasket_sysfs_create_mapping had a legacy device, the entries will be created
112  * for it, as well.
113  */
114 int gasket_sysfs_create_entries(struct device *device,
115                                 const struct gasket_sysfs_attribute *attrs);
116
117 /*
118  * Removes a device mapping from the global table.
119  * @device: Device to unmap.
120  *
121  * Description: Removes the device->Gasket device mapping from the internal
122  * table.
123  */
124 void gasket_sysfs_remove_mapping(struct device *device);
125
126 /*
127  * User data lookup based on kernel device structure.
128  * @device: Kernel device structure.
129  *
130  * Description: Returns the user data associated with "device" in a prior call
131  * to gasket_sysfs_create_entries. Returns NULL if no mapping can be found.
132  * Upon success, this call take a reference to internal sysfs data that must be
133  * released with gasket_sysfs_put_device_data. While this reference is held, the
134  * underlying device sysfs information/structure will remain valid/will not be
135  * deleted.
136  */
137 struct gasket_dev *gasket_sysfs_get_device_data(struct device *device);
138
139 /*
140  * Releases a references to internal data.
141  * @device: Kernel device structure.
142  * @dev: Gasket device descriptor (returned by gasket_sysfs_get_device_data).
143  */
144 void gasket_sysfs_put_device_data(struct device *device,
145                                   struct gasket_dev *gasket_dev);
146
147 /*
148  * Gasket-specific attribute lookup.
149  * @device: Kernel device structure.
150  * @attr: Device attribute to look up.
151  *
152  * Returns the Gasket sysfs attribute associated with the kernel device
153  * attribute and device structure itself. Upon success, this call will take a
154  * reference to internal sysfs data that must be released with a call to
155  * gasket_sysfs_get_device_data. While this reference is held, the underlying
156  * device sysfs information/structure will remain valid/will not be deleted.
157  */
158 struct gasket_sysfs_attribute *
159 gasket_sysfs_get_attr(struct device *device, struct device_attribute *attr);
160
161 /*
162  * Releases a references to internal data.
163  * @device: Kernel device structure.
164  * @attr: Gasket sysfs attribute descriptor (returned by
165  *        gasket_sysfs_get_attr).
166  */
167 void gasket_sysfs_put_attr(struct device *device,
168                            struct gasket_sysfs_attribute *attr);
169
170 /*
171  * Write to a register sysfs node.
172  * @buf: NULL-terminated data being written.
173  * @count: number of bytes in the "buf" argument.
174  */
175 ssize_t gasket_sysfs_register_store(struct device *device,
176                                     struct device_attribute *attr,
177                                     const char *buf, size_t count);
178
179 #endif /* __GASKET_SYSFS_H__ */