• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 /*
34  * Terminator struct for a gasket_sysfs_attr array. Must be at the end of
35  * all gasket_sysfs_attribute arrays.
36  */
37 #define GASKET_END_OF_ATTR_ARRAY                                               \
38 	{                                                                      \
39 		.attr = __ATTR_NULL,				\
40 		.data.attr_type = 0,				\
41 	}
42 
43 /*
44  * Pairing of sysfs attribute and user data.
45  * Used in lookups in sysfs "show" functions to return attribute metadata.
46  */
47 struct gasket_sysfs_attribute {
48 	/* The underlying sysfs device attribute associated with this data. */
49 	struct device_attribute attr;
50 
51 	/* User-specified data to associate with the attribute. */
52 	union {
53 		struct bar_address_ {
54 			ulong bar;
55 			ulong offset;
56 		} bar_address;
57 		uint attr_type;
58 	} data;
59 
60 	/*
61 	 * Function pointer to a callback to be invoked when this attribute is
62 	 * written (if so configured). The arguments are to the Gasket device
63 	 * pointer, the enclosing gasket_attr structure, and the value written.
64 	 * The callback should perform any logging necessary, as errors cannot
65 	 * be returned from the callback.
66 	 */
67 	void (*write_callback)(struct gasket_dev *dev,
68 			       struct gasket_sysfs_attribute *attr,
69 			       ulong value);
70 };
71 
72 #define GASKET_SYSFS_RO(_name, _show_function, _attr_type)                     \
73 	{                                                                      \
74 		.attr = __ATTR(_name, 0444, _show_function, NULL),          \
75 		.data.attr_type = _attr_type                                   \
76 	}
77 
78 /* Initializes the Gasket sysfs subsystem.
79  *
80  * Description: Performs one-time initialization. Must be called before usage
81  * at [Gasket] module load time.
82  */
83 void gasket_sysfs_init(void);
84 
85 /*
86  * Create an entry in mapping_data between a device and a Gasket device.
87  * @device: Device struct to map to.
88  * @gasket_dev: The dev struct associated with the driver controlling @device.
89  *
90  * Description: This function maps a gasket_dev* to a device*. This mapping can
91  * be used in sysfs_show functions to get a handle to the gasket_dev struct
92  * controlling the device node.
93  *
94  * If this function is not called before gasket_sysfs_create_entries, a warning
95  * will be logged.
96  */
97 int gasket_sysfs_create_mapping(struct device *device,
98 				struct gasket_dev *gasket_dev);
99 
100 /*
101  * Creates bulk entries in sysfs.
102  * @device: Kernel device structure.
103  * @attrs: List of attributes/sysfs entries to create.
104  *
105  * Description: Creates each sysfs entry described in "attrs". Can be called
106  * multiple times for a given @device. If the gasket_dev specified in
107  * gasket_sysfs_create_mapping had a legacy device, the entries will be created
108  * for it, as well.
109  */
110 int gasket_sysfs_create_entries(struct device *device,
111 				const struct gasket_sysfs_attribute *attrs);
112 
113 /*
114  * Removes a device mapping from the global table.
115  * @device: Device to unmap.
116  *
117  * Description: Removes the device->Gasket device mapping from the internal
118  * table.
119  */
120 void gasket_sysfs_remove_mapping(struct device *device);
121 
122 /*
123  * User data lookup based on kernel device structure.
124  * @device: Kernel device structure.
125  *
126  * Description: Returns the user data associated with "device" in a prior call
127  * to gasket_sysfs_create_entries. Returns NULL if no mapping can be found.
128  * Upon success, this call take a reference to internal sysfs data that must be
129  * released with gasket_sysfs_put_device_data. While this reference is held, the
130  * underlying device sysfs information/structure will remain valid/will not be
131  * deleted.
132  */
133 struct gasket_dev *gasket_sysfs_get_device_data(struct device *device);
134 
135 /*
136  * Releases a references to internal data.
137  * @device: Kernel device structure.
138  * @dev: Gasket device descriptor (returned by gasket_sysfs_get_device_data).
139  */
140 void gasket_sysfs_put_device_data(struct device *device,
141 				  struct gasket_dev *gasket_dev);
142 
143 /*
144  * Gasket-specific attribute lookup.
145  * @device: Kernel device structure.
146  * @attr: Device attribute to look up.
147  *
148  * Returns the Gasket sysfs attribute associated with the kernel device
149  * attribute and device structure itself. Upon success, this call will take a
150  * reference to internal sysfs data that must be released with a call to
151  * gasket_sysfs_put_attr. While this reference is held, the underlying device
152  * sysfs information/structure will remain valid/will not be deleted.
153  */
154 struct gasket_sysfs_attribute *
155 gasket_sysfs_get_attr(struct device *device, struct device_attribute *attr);
156 
157 /*
158  * Releases a references to internal data.
159  * @device: Kernel device structure.
160  * @attr: Gasket sysfs attribute descriptor (returned by
161  *        gasket_sysfs_get_attr).
162  */
163 void gasket_sysfs_put_attr(struct device *device,
164 			   struct gasket_sysfs_attribute *attr);
165 
166 /*
167  * Write to a register sysfs node.
168  * @buf: NULL-terminated data being written.
169  * @count: number of bytes in the "buf" argument.
170  */
171 ssize_t gasket_sysfs_register_store(struct device *device,
172 				    struct device_attribute *attr,
173 				    const char *buf, size_t count);
174 
175 #endif /* __GASKET_SYSFS_H__ */
176