From 3c702e9987e261042a07e43460a8148be254412e Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 21 Oct 2015 15:29:53 +0200 Subject: gpio: add a userspace chardev ABI for GPIOs A new chardev that is to be used for userspace GPIO access is added in this patch. It is intended to gradually replace the horribly broken sysfs ABI. Using a chardev has many upsides: - All operations are per-gpiochip, which is the actual device underlying the GPIOs, making us tie in to the kernel device model properly. - Hotpluggable GPIO controllers can come and go, as this kind of problem has been know to userspace for character devices since ages, and if a gpiochip handle is held in userspace we know we will break something, whereas the sysfs is stateless. - The one-value-per-file rule of sysfs is really hard to maintain when you want to twist more than one knob at a time, for example have in-kernel APIs to switch several GPIO lines at the same time, and this will be possible to do with a single ioctl() from userspace, saving a lot of context switching. We also need to add a new bus type for GPIO. This is necessary for example for userspace coldplug, where sysfs is traversed to find the boot-time device nodes and create the character devices in /dev. This new chardev ABI is *non* *optional* and can be counted on to be present in the future, emphasizing the preference of this ABI. The ABI only implements one single ioctl() to get the name and number of GPIO lines of a chip. Even this is debatable: see it as a minimal example for review. This ABI shall be ruthlessly reviewed and etched in stone. The old /sys/class/gpio is still optional to compile in, but will be deprecated. Unique device IDs are created using IDR, which is overkill and insanely scalable, but also well tested. Cc: Johan Hovold Cc: Michael Welling Cc: Markus Pargmann Cc: Greg Kroah-Hartman Cc: Arnd Bergmann Signed-off-by: Linus Walleij --- include/uapi/linux/Kbuild | 1 + include/uapi/linux/gpio.h | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 include/uapi/linux/gpio.h (limited to 'include/uapi') diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild index ebd10e624598..5c9ae6a9b7f5 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild @@ -138,6 +138,7 @@ header-y += genetlink.h header-y += gen_stats.h header-y += gfs2_ondisk.h header-y += gigaset_dev.h +header-y += gpio.h header-y += gsmmux.h header-y += hdlcdrv.h header-y += hdlc.h diff --git a/include/uapi/linux/gpio.h b/include/uapi/linux/gpio.h new file mode 100644 index 000000000000..3188a87bdaa0 --- /dev/null +++ b/include/uapi/linux/gpio.h @@ -0,0 +1,28 @@ +/* + * - userspace ABI for the GPIO character devices + * + * Copyright (C) 2015 Linus Walleij + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ +#ifndef _UAPI_GPIO_H_ +#define _UAPI_GPIO_H_ + +#include +#include + +/** + * struct gpiochip_info - Information about a certain GPIO chip + * @name: the name of this GPIO chip + * @lines: number of GPIO lines on this chip + */ +struct gpiochip_info { + char name[32]; + __u32 lines; +}; + +#define GPIO_GET_CHIPINFO_IOCTL _IOR('o', 0x01, struct gpiochip_info) + +#endif /* _UAPI_GPIO_H_ */ -- cgit From df4878e969ccc047da45d2cd3af5d08031da1593 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 12 Feb 2016 14:48:23 +0100 Subject: gpio: store reflect the label to userspace The gpio_chip label is useful for userspace to understand what kind of GPIO chip it is dealing with. Let's store a copy of this label in the gpio_device, add it to the struct passed to userspace for GPIO_GET_CHIPINFO_IOCTL and modify lsgpio to show it. Signed-off-by: Linus Walleij --- include/uapi/linux/gpio.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/uapi') diff --git a/include/uapi/linux/gpio.h b/include/uapi/linux/gpio.h index 3188a87bdaa0..3f93e1bcd3dd 100644 --- a/include/uapi/linux/gpio.h +++ b/include/uapi/linux/gpio.h @@ -16,10 +16,12 @@ /** * struct gpiochip_info - Information about a certain GPIO chip * @name: the name of this GPIO chip + * @label: a functional name for this GPIO chip * @lines: number of GPIO lines on this chip */ struct gpiochip_info { char name[32]; + char label[32]; __u32 lines; }; -- cgit From 521a2ad6f862a28e2e43cb3e254a26bf0f9452e9 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 12 Feb 2016 22:25:22 +0100 Subject: gpio: add userspace ABI for GPIO line information This adds a GPIO line ABI for getting name, label and a few select flags from the kernel. This hides the kernel internals and only tells userspace what it may need to know: the different in-kernel consumers are masked behind the flag "kernel" and that is all userspace needs to know. However electric characteristics like active low, open drain etc are reflected to userspace, as this is important information. We provide information on all lines on all chips, later on we will likely add a flag for the chardev consumer so we can filter and display only the lines userspace actually uses in e.g. lsgpio, but then we first need an ABI for userspace to grab and use (get/set/select direction) a GPIO line. Sample output from "lsgpio" on ux500: GPIO chip: gpiochip7, "8011e000.gpio", 32 GPIO lines line 0: unnamed unlabeled line 1: unnamed unlabeled (...) line 25: unnamed "SFH7741 Proximity Sensor" [kernel output open-drain] line 26: unnamed unlabeled (...) Tested-by: Michael Welling Signed-off-by: Linus Walleij --- include/uapi/linux/gpio.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'include/uapi') diff --git a/include/uapi/linux/gpio.h b/include/uapi/linux/gpio.h index 3f93e1bcd3dd..416ce47f2291 100644 --- a/include/uapi/linux/gpio.h +++ b/include/uapi/linux/gpio.h @@ -25,6 +25,32 @@ struct gpiochip_info { __u32 lines; }; +/* Line is in use by the kernel */ +#define GPIOLINE_FLAG_KERNEL (1UL << 0) +#define GPIOLINE_FLAG_IS_OUT (1UL << 1) +#define GPIOLINE_FLAG_ACTIVE_LOW (1UL << 2) +#define GPIOLINE_FLAG_OPEN_DRAIN (1UL << 3) +#define GPIOLINE_FLAG_OPEN_SOURCE (1UL << 4) + +/** + * struct gpioline_info - Information about a certain GPIO line + * @line_offset: the local offset on this GPIO device, fill in when + * requesting information from the kernel + * @flags: various flags for this line + * @name: the name of this GPIO line + * @label: a functional name for this GPIO line + * @kernel: this GPIO is in use by the kernel + * @out: this GPIO is an output line (false means it is an input) + * @active_low: this GPIO is active low + */ +struct gpioline_info { + __u32 line_offset; + __u32 flags; + char name[32]; + char label[32]; +}; + #define GPIO_GET_CHIPINFO_IOCTL _IOR('o', 0x01, struct gpiochip_info) +#define GPIO_GET_LINEINFO_IOCTL _IOWR('o', 0x02, struct gpioline_info) #endif /* _UAPI_GPIO_H_ */ -- cgit From 214338e372af2b856af07978daa771dbe087f990 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 25 Feb 2016 21:01:48 +0100 Subject: gpio: present the consumer of a line to userspace I named the field representing the current user of GPIO line as "label" but this is too vague and ambiguous. Before anyone gets confused, rename it to "consumer" and indicate clearly in the documentation that this is a string set by the user of the line. Also clean up leftovers in the documentation. Signed-off-by: Linus Walleij --- include/uapi/linux/gpio.h | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'include/uapi') diff --git a/include/uapi/linux/gpio.h b/include/uapi/linux/gpio.h index 416ce47f2291..dfe8ade2742d 100644 --- a/include/uapi/linux/gpio.h +++ b/include/uapi/linux/gpio.h @@ -15,8 +15,9 @@ /** * struct gpiochip_info - Information about a certain GPIO chip - * @name: the name of this GPIO chip - * @label: a functional name for this GPIO chip + * @name: the Linux kernel name of this GPIO chip + * @label: a functional name for this GPIO chip, such as a product + * number, may be NULL * @lines: number of GPIO lines on this chip */ struct gpiochip_info { @@ -34,20 +35,21 @@ struct gpiochip_info { /** * struct gpioline_info - Information about a certain GPIO line - * @line_offset: the local offset on this GPIO device, fill in when - * requesting information from the kernel + * @line_offset: the local offset on this GPIO device, fill this in when + * requesting the line information from the kernel * @flags: various flags for this line - * @name: the name of this GPIO line - * @label: a functional name for this GPIO line - * @kernel: this GPIO is in use by the kernel - * @out: this GPIO is an output line (false means it is an input) - * @active_low: this GPIO is active low + * @name: the name of this GPIO line, such as the output pin of the line on the + * chip, a rail or a pin header name on a board, as specified by the gpio + * chip, may be NULL + * @consumer: a functional name for the consumer of this GPIO line as set by + * whatever is using it, will be NULL if there is no current user but may + * also be NULL if the consumer doesn't set this up */ struct gpioline_info { __u32 line_offset; __u32 flags; char name[32]; - char label[32]; + char consumer[32]; }; #define GPIO_GET_CHIPINFO_IOCTL _IOR('o', 0x01, struct gpiochip_info) -- cgit From fae98164463948eb31d638fe207c25a3d2b9312f Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 10 Mar 2016 15:48:06 +0700 Subject: gpio: uapi: use 0xB4 as ioctl() major The previous 'o' is in conflict and not very orderly assigned. We want to select an ioctl() major that does not conflict with the existining ones. Add the new reserved major (0xB4) to Documentation/ioctl/ioctl-number.txt Fixes: 3c702e9987e2 ("gpio: add a userspace chardev ABI for GPIOs") Suggested-by: Arnd Bergmann Signed-off-by: Linus Walleij --- include/uapi/linux/gpio.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/uapi') diff --git a/include/uapi/linux/gpio.h b/include/uapi/linux/gpio.h index dfe8ade2742d..d0a3cac72250 100644 --- a/include/uapi/linux/gpio.h +++ b/include/uapi/linux/gpio.h @@ -52,7 +52,7 @@ struct gpioline_info { char consumer[32]; }; -#define GPIO_GET_CHIPINFO_IOCTL _IOR('o', 0x01, struct gpiochip_info) -#define GPIO_GET_LINEINFO_IOCTL _IOWR('o', 0x02, struct gpioline_info) +#define GPIO_GET_CHIPINFO_IOCTL _IOR(0xB4, 0x01, struct gpiochip_info) +#define GPIO_GET_LINEINFO_IOCTL _IOWR(0xB4, 0x02, struct gpioline_info) #endif /* _UAPI_GPIO_H_ */ -- cgit