Skip to content

Commit b53911a

Browse files
warthog618brgl
authored andcommitted
gpio: uapi: define uAPI v2
Add a new version of the uAPI to address existing 32/64-bit alignment issues, add support for debounce and event sequence numbers, allow requested lines with different configurations, and provide some future proofing by adding padding reserved for future use. The alignment issue relates to the gpioevent_data, which packs to different sizes on 32-bit and 64-bit platforms. That creates problems for 32-bit apps running on 64-bit kernels. uAPI v2 addresses that particular issue, and the problem more generally, by adding pad fields that explicitly pad structs out to 64-bit boundaries, so they will pack to the same size now, and even if some of the reserved padding is used for __u64 fields in the future. The new structs have been analysed with pahole to ensure that they are sized as expected and contain no implicit padding. The lack of future proofing in v1 makes it impossible to, for example, add the debounce feature that is included in v2. The future proofing is addressed by providing configurable attributes in line config and reserved padding in all structs for future features. Specifically, the line request, config, info, info_changed and event structs receive updated versions and new ioctls. As the majority of the structs and ioctls were being replaced, it is opportune to rework some of the other aspects of the uAPI: v1 has three different flags fields, each with their own separate bit definitions. In v2 that is collapsed to one - gpio_v2_line_flag. The handle and event requests are merged into a single request, the line request, as the two requests were mostly the same other than the edge detection provided by event requests. As a byproduct, the v2 uAPI allows for multiple lines producing edge events on the same line handle. This is a new capability as v1 only supports a single line in an event request. As a consequence, there are now only two types of file handle to be concerned with, the chip and the line, and it is clearer which ioctls apply to which type of handle. There is also some minor renaming of fields for consistency compared to their v1 counterparts, e.g. offset rather than lineoffset or line_offset, and consumer rather than consumer_label. Additionally, v1 GPIOHANDLES_MAX becomes GPIO_V2_LINES_MAX in v2 for clarity, and the gpiohandle_data __u8 array becomes a bitmap in gpio_v2_line_values. The v2 uAPI is mostly a reorganisation and extension of v1, so userspace code, particularly libgpiod, should readily port to it. Signed-off-by: Kent Gibson <[email protected]> Reviewed-by: Andy Shevchenko <[email protected]> Signed-off-by: Bartosz Golaszewski <[email protected]>
1 parent 539430f commit b53911a

File tree

1 file changed

+284
-7
lines changed

1 file changed

+284
-7
lines changed

include/uapi/linux/gpio.h

Lines changed: 284 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,14 @@
1111
#ifndef _UAPI_GPIO_H_
1212
#define _UAPI_GPIO_H_
1313

14+
#include <linux/const.h>
1415
#include <linux/ioctl.h>
1516
#include <linux/types.h>
1617

1718
/*
1819
* The maximum size of name and label arrays.
20+
*
21+
* Must be a multiple of 8 to ensure 32/64-bit alignment of structs.
1922
*/
2023
#define GPIO_MAX_NAME_SIZE 32
2124

@@ -32,6 +35,265 @@ struct gpiochip_info {
3235
__u32 lines;
3336
};
3437

38+
/*
39+
* Maximum number of requested lines.
40+
*
41+
* Must be no greater than 64, as bitmaps are restricted here to 64-bits
42+
* for simplicity, and a multiple of 2 to ensure 32/64-bit alignment of
43+
* structs.
44+
*/
45+
#define GPIO_V2_LINES_MAX 64
46+
47+
/*
48+
* The maximum number of configuration attributes associated with a line
49+
* request.
50+
*/
51+
#define GPIO_V2_LINE_NUM_ATTRS_MAX 10
52+
53+
/**
54+
* enum gpio_v2_line_flag - &struct gpio_v2_line_attribute.flags values
55+
* @GPIO_V2_LINE_FLAG_USED: line is not available for request
56+
* @GPIO_V2_LINE_FLAG_ACTIVE_LOW: line active state is physical low
57+
* @GPIO_V2_LINE_FLAG_INPUT: line is an input
58+
* @GPIO_V2_LINE_FLAG_OUTPUT: line is an output
59+
* @GPIO_V2_LINE_FLAG_EDGE_RISING: line detects rising (inactive to active)
60+
* edges
61+
* @GPIO_V2_LINE_FLAG_EDGE_FALLING: line detects falling (active to
62+
* inactive) edges
63+
* @GPIO_V2_LINE_FLAG_OPEN_DRAIN: line is an open drain output
64+
* @GPIO_V2_LINE_FLAG_OPEN_SOURCE: line is an open source output
65+
* @GPIO_V2_LINE_FLAG_BIAS_PULL_UP: line has pull-up bias enabled
66+
* @GPIO_V2_LINE_FLAG_BIAS_PULL_DOWN: line has pull-down bias enabled
67+
* @GPIO_V2_LINE_FLAG_BIAS_DISABLED: line has bias disabled
68+
*/
69+
enum gpio_v2_line_flag {
70+
GPIO_V2_LINE_FLAG_USED = _BITULL(0),
71+
GPIO_V2_LINE_FLAG_ACTIVE_LOW = _BITULL(1),
72+
GPIO_V2_LINE_FLAG_INPUT = _BITULL(2),
73+
GPIO_V2_LINE_FLAG_OUTPUT = _BITULL(3),
74+
GPIO_V2_LINE_FLAG_EDGE_RISING = _BITULL(4),
75+
GPIO_V2_LINE_FLAG_EDGE_FALLING = _BITULL(5),
76+
GPIO_V2_LINE_FLAG_OPEN_DRAIN = _BITULL(6),
77+
GPIO_V2_LINE_FLAG_OPEN_SOURCE = _BITULL(7),
78+
GPIO_V2_LINE_FLAG_BIAS_PULL_UP = _BITULL(8),
79+
GPIO_V2_LINE_FLAG_BIAS_PULL_DOWN = _BITULL(9),
80+
GPIO_V2_LINE_FLAG_BIAS_DISABLED = _BITULL(10),
81+
};
82+
83+
/**
84+
* struct gpio_v2_line_values - Values of GPIO lines
85+
* @bits: a bitmap containing the value of the lines, set to 1 for active
86+
* and 0 for inactive.
87+
* @mask: a bitmap identifying the lines to get or set, with each bit
88+
* number corresponding to the index into &struct
89+
* gpio_v2_line_request.offsets.
90+
*/
91+
struct gpio_v2_line_values {
92+
__aligned_u64 bits;
93+
__aligned_u64 mask;
94+
};
95+
96+
/**
97+
* enum gpio_v2_line_attr_id - &struct gpio_v2_line_attribute.id values
98+
* identifying which field of the attribute union is in use.
99+
* @GPIO_V2_LINE_ATTR_ID_FLAGS: flags field is in use
100+
* @GPIO_V2_LINE_ATTR_ID_OUTPUT_VALUES: values field is in use
101+
* @GPIO_V2_LINE_ATTR_ID_DEBOUNCE: debounce_period_us is in use
102+
*/
103+
enum gpio_v2_line_attr_id {
104+
GPIO_V2_LINE_ATTR_ID_FLAGS = 1,
105+
GPIO_V2_LINE_ATTR_ID_OUTPUT_VALUES = 2,
106+
GPIO_V2_LINE_ATTR_ID_DEBOUNCE = 3,
107+
};
108+
109+
/**
110+
* struct gpio_v2_line_attribute - a configurable attribute of a line
111+
* @id: attribute identifier with value from &enum gpio_v2_line_attr_id
112+
* @padding: reserved for future use and must be zero filled
113+
* @flags: if id is GPIO_V2_LINE_ATTR_ID_FLAGS, the flags for the GPIO
114+
* line, with values from enum gpio_v2_line_flag, such as
115+
* GPIO_V2_LINE_FLAG_ACTIVE_LOW, GPIO_V2_LINE_FLAG_OUTPUT etc, OR:ed
116+
* together. This overrides the default flags contained in the &struct
117+
* gpio_v2_line_config for the associated line.
118+
* @values: if id is GPIO_V2_LINE_ATTR_ID_OUTPUT_VALUES, a bitmap
119+
* containing the values to which the lines will be set, with each bit
120+
* number corresponding to the index into &struct
121+
* gpio_v2_line_request.offsets.
122+
* @debounce_period_us: if id is GPIO_V2_LINE_ATTR_ID_DEBOUNCE, the desired
123+
* debounce period, in microseconds
124+
*/
125+
struct gpio_v2_line_attribute {
126+
__u32 id;
127+
__u32 padding;
128+
union {
129+
__aligned_u64 flags;
130+
__aligned_u64 values;
131+
__u32 debounce_period_us;
132+
};
133+
};
134+
135+
/**
136+
* struct gpio_v2_line_config_attribute - a configuration attribute
137+
* associated with one or more of the requested lines.
138+
* @attr: the configurable attribute
139+
* @mask: a bitmap identifying the lines to which the attribute applies,
140+
* with each bit number corresponding to the index into &struct
141+
* gpio_v2_line_request.offsets.
142+
*/
143+
struct gpio_v2_line_config_attribute {
144+
struct gpio_v2_line_attribute attr;
145+
__aligned_u64 mask;
146+
};
147+
148+
/**
149+
* struct gpio_v2_line_config - Configuration for GPIO lines
150+
* @flags: flags for the GPIO lines, with values from enum
151+
* gpio_v2_line_flag, such as GPIO_V2_LINE_FLAG_ACTIVE_LOW,
152+
* GPIO_V2_LINE_FLAG_OUTPUT etc, OR:ed together. This is the default for
153+
* all requested lines but may be overridden for particular lines using
154+
* attrs.
155+
* @num_attrs: the number of attributes in attrs
156+
* @padding: reserved for future use and must be zero filled
157+
* @attrs: the configuration attributes associated with the requested
158+
* lines. Any attribute should only be associated with a particular line
159+
* once. If an attribute is associated with a line multiple times then the
160+
* first occurrence (i.e. lowest index) has precedence.
161+
*/
162+
struct gpio_v2_line_config {
163+
__aligned_u64 flags;
164+
__u32 num_attrs;
165+
/* Pad to fill implicit padding and reserve space for future use. */
166+
__u32 padding[5];
167+
struct gpio_v2_line_config_attribute attrs[GPIO_V2_LINE_NUM_ATTRS_MAX];
168+
};
169+
170+
/**
171+
* struct gpio_v2_line_request - Information about a request for GPIO lines
172+
* @offsets: an array of desired lines, specified by offset index for the
173+
* associated GPIO chip
174+
* @consumer: a desired consumer label for the selected GPIO lines such as
175+
* "my-bitbanged-relay"
176+
* @config: requested configuration for the lines.
177+
* @num_lines: number of lines requested in this request, i.e. the number
178+
* of valid fields in the GPIO_V2_LINES_MAX sized arrays, set to 1 to
179+
* request a single line
180+
* @event_buffer_size: a suggested minimum number of line events that the
181+
* kernel should buffer. This is only relevant if edge detection is
182+
* enabled in the configuration. Note that this is only a suggested value
183+
* and the kernel may allocate a larger buffer or cap the size of the
184+
* buffer. If this field is zero then the buffer size defaults to a minimum
185+
* of num_lines*16.
186+
* @padding: reserved for future use and must be zero filled
187+
* @fd: if successful this field will contain a valid anonymous file handle
188+
* after a GPIO_GET_LINE_IOCTL operation, zero or negative value means
189+
* error
190+
*/
191+
struct gpio_v2_line_request {
192+
__u32 offsets[GPIO_V2_LINES_MAX];
193+
char consumer[GPIO_MAX_NAME_SIZE];
194+
struct gpio_v2_line_config config;
195+
__u32 num_lines;
196+
__u32 event_buffer_size;
197+
/* Pad to fill implicit padding and reserve space for future use. */
198+
__u32 padding[5];
199+
__s32 fd;
200+
};
201+
202+
/**
203+
* struct gpio_v2_line_info - Information about a certain GPIO line
204+
* @name: the name of this GPIO line, such as the output pin of the line on
205+
* the chip, a rail or a pin header name on a board, as specified by the
206+
* GPIO chip, may be empty
207+
* @consumer: a functional name for the consumer of this GPIO line as set
208+
* by whatever is using it, will be empty if there is no current user but
209+
* may also be empty if the consumer doesn't set this up
210+
* @flags: flags for the GPIO line, such as GPIO_V2_LINE_FLAG_ACTIVE_LOW,
211+
* GPIO_V2_LINE_FLAG_OUTPUT etc, OR:ed together
212+
* @offset: the local offset on this GPIO chip, fill this in when
213+
* requesting the line information from the kernel
214+
* @num_attrs: the number of attributes in attrs
215+
* @attrs: the configuration attributes associated with the line
216+
* @padding: reserved for future use
217+
*/
218+
struct gpio_v2_line_info {
219+
char name[GPIO_MAX_NAME_SIZE];
220+
char consumer[GPIO_MAX_NAME_SIZE];
221+
__u32 offset;
222+
__u32 num_attrs;
223+
__aligned_u64 flags;
224+
struct gpio_v2_line_attribute attrs[GPIO_V2_LINE_NUM_ATTRS_MAX];
225+
/* Space reserved for future use. */
226+
__u32 padding[4];
227+
};
228+
229+
/**
230+
* enum gpio_v2_line_changed_type - &struct gpio_v2_line_changed.event_type
231+
* values
232+
* @GPIO_V2_LINE_CHANGED_REQUESTED: line has been requested
233+
* @GPIO_V2_LINE_CHANGED_RELEASED: line has been released
234+
* @GPIO_V2_LINE_CHANGED_CONFIG: line has been reconfigured
235+
*/
236+
enum gpio_v2_line_changed_type {
237+
GPIO_V2_LINE_CHANGED_REQUESTED = 1,
238+
GPIO_V2_LINE_CHANGED_RELEASED = 2,
239+
GPIO_V2_LINE_CHANGED_CONFIG = 3,
240+
};
241+
242+
/**
243+
* struct gpio_v2_line_info_changed - Information about a change in status
244+
* of a GPIO line
245+
* @info: updated line information
246+
* @timestamp_ns: estimate of time of status change occurrence, in nanoseconds
247+
* @event_type: the type of change with a value from enum
248+
* gpio_v2_line_changed_type
249+
* @padding: reserved for future use
250+
*/
251+
struct gpio_v2_line_info_changed {
252+
struct gpio_v2_line_info info;
253+
__aligned_u64 timestamp_ns;
254+
__u32 event_type;
255+
/* Pad struct to 64-bit boundary and reserve space for future use. */
256+
__u32 padding[5];
257+
};
258+
259+
/**
260+
* enum gpio_v2_line_event_id - &struct gpio_v2_line_event.id values
261+
* @GPIO_V2_LINE_EVENT_RISING_EDGE: event triggered by a rising edge
262+
* @GPIO_V2_LINE_EVENT_FALLING_EDGE: event triggered by a falling edge
263+
*/
264+
enum gpio_v2_line_event_id {
265+
GPIO_V2_LINE_EVENT_RISING_EDGE = 1,
266+
GPIO_V2_LINE_EVENT_FALLING_EDGE = 2,
267+
};
268+
269+
/**
270+
* struct gpio_v2_line_event - The actual event being pushed to userspace
271+
* @timestamp_ns: best estimate of time of event occurrence, in nanoseconds.
272+
* The timestamp_ns is read from CLOCK_MONOTONIC and is intended to allow the
273+
* accurate measurement of the time between events. It does not provide
274+
* the wall-clock time.
275+
* @id: event identifier with value from enum gpio_v2_line_event_id
276+
* @offset: the offset of the line that triggered the event
277+
* @seqno: the sequence number for this event in the sequence of events for
278+
* all the lines in this line request
279+
* @line_seqno: the sequence number for this event in the sequence of
280+
* events on this particular line
281+
* @padding: reserved for future use
282+
*/
283+
struct gpio_v2_line_event {
284+
__aligned_u64 timestamp_ns;
285+
__u32 id;
286+
__u32 offset;
287+
__u32 seqno;
288+
__u32 line_seqno;
289+
/* Space reserved for future use. */
290+
__u32 padding[6];
291+
};
292+
293+
/*
294+
* ABI v1
295+
*/
296+
35297
/* Informational flags */
36298
#define GPIOLINE_FLAG_KERNEL (1UL << 0) /* Line used by the kernel */
37299
#define GPIOLINE_FLAG_IS_OUT (1UL << 1)
@@ -149,8 +411,6 @@ struct gpiohandle_config {
149411
__u32 padding[4]; /* padding for future use */
150412
};
151413

152-
#define GPIOHANDLE_SET_CONFIG_IOCTL _IOWR(0xB4, 0x0a, struct gpiohandle_config)
153-
154414
/**
155415
* struct gpiohandle_data - Information of values on a GPIO handle
156416
* @values: when getting the state of lines this contains the current
@@ -161,9 +421,6 @@ struct gpiohandle_data {
161421
__u8 values[GPIOHANDLES_MAX];
162422
};
163423

164-
#define GPIOHANDLE_GET_LINE_VALUES_IOCTL _IOWR(0xB4, 0x08, struct gpiohandle_data)
165-
#define GPIOHANDLE_SET_LINE_VALUES_IOCTL _IOWR(0xB4, 0x09, struct gpiohandle_data)
166-
167424
/* Eventrequest flags */
168425
#define GPIOEVENT_REQUEST_RISING_EDGE (1UL << 0)
169426
#define GPIOEVENT_REQUEST_FALLING_EDGE (1UL << 1)
@@ -207,11 +464,31 @@ struct gpioevent_data {
207464
__u32 id;
208465
};
209466

467+
/*
468+
* v1 and v2 ioctl()s
469+
*/
210470
#define GPIO_GET_CHIPINFO_IOCTL _IOR(0xB4, 0x01, struct gpiochip_info)
471+
#define GPIO_GET_LINEINFO_UNWATCH_IOCTL _IOWR(0xB4, 0x0C, __u32)
472+
473+
/*
474+
* v2 ioctl()s
475+
*/
476+
#define GPIO_V2_GET_LINEINFO_IOCTL _IOWR(0xB4, 0x05, struct gpio_v2_line_info)
477+
#define GPIO_V2_GET_LINEINFO_WATCH_IOCTL _IOWR(0xB4, 0x06, struct gpio_v2_line_info)
478+
#define GPIO_V2_GET_LINE_IOCTL _IOWR(0xB4, 0x07, struct gpio_v2_line_request)
479+
#define GPIO_V2_LINE_SET_CONFIG_IOCTL _IOWR(0xB4, 0x0D, struct gpio_v2_line_config)
480+
#define GPIO_V2_LINE_GET_VALUES_IOCTL _IOWR(0xB4, 0x0E, struct gpio_v2_line_values)
481+
#define GPIO_V2_LINE_SET_VALUES_IOCTL _IOWR(0xB4, 0x0F, struct gpio_v2_line_values)
482+
483+
/*
484+
* v1 ioctl()s
485+
*/
211486
#define GPIO_GET_LINEINFO_IOCTL _IOWR(0xB4, 0x02, struct gpioline_info)
212-
#define GPIO_GET_LINEINFO_WATCH_IOCTL _IOWR(0xB4, 0x0b, struct gpioline_info)
213-
#define GPIO_GET_LINEINFO_UNWATCH_IOCTL _IOWR(0xB4, 0x0c, __u32)
214487
#define GPIO_GET_LINEHANDLE_IOCTL _IOWR(0xB4, 0x03, struct gpiohandle_request)
215488
#define GPIO_GET_LINEEVENT_IOCTL _IOWR(0xB4, 0x04, struct gpioevent_request)
489+
#define GPIOHANDLE_GET_LINE_VALUES_IOCTL _IOWR(0xB4, 0x08, struct gpiohandle_data)
490+
#define GPIOHANDLE_SET_LINE_VALUES_IOCTL _IOWR(0xB4, 0x09, struct gpiohandle_data)
491+
#define GPIOHANDLE_SET_CONFIG_IOCTL _IOWR(0xB4, 0x0A, struct gpiohandle_config)
492+
#define GPIO_GET_LINEINFO_WATCH_IOCTL _IOWR(0xB4, 0x0B, struct gpioline_info)
216493

217494
#endif /* _UAPI_GPIO_H_ */

0 commit comments

Comments
 (0)