diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-04-13 20:10:58 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-04-13 20:10:58 -0700 |
| commit | 1334d2a3b3235d062e5e1f51aebe7a64ed57cf72 (patch) | |
| tree | d15ea79b8884902e196dc76210829594d70a1fb7 /Documentation/driver-api | |
| parent | fbfb6bd927c9ac6ea155471cc7ced8e16b37c2cb (diff) | |
| parent | ca13ab654064fee86d6e7c9e87d0af7789561509 (diff) | |
Merge tag 'gpio-updates-for-v7.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux
Pull gpio updates from Bartosz Golaszewski:
"For this merge window we have two new drivers: support for
GPIO-signalled ACPI events on Intel platforms and a generic
GPIO-over-pinctrl driver using the ARM SCMI protocol for
controlling pins.
Several things have been reworked in GPIO core: we unduplicated GPIO
hog handling, reduced the number of SRCU locks and dereferences,
improved support for software-node-based lookup and removed more
legacy code after converting remaining users to modern alternatives.
There's also a number of driver reworks and refactoring, documentation
updates, some bug-fixes and new tests.
GPIO core:
- defer probe on software node lookups when the remote software node
exists but has not been registered as a firmware node yet
- unify GPIO hog handling by moving code duplicated in OF and ACPI
modules into GPIO core and allow setting up hogs with software
nodes
- allow matching GPIO controllers by secondary firmware node if
matching by primary does not succeed
- demote deferral warnings to debug level as they are quite normal
when using software nodes which don't support fw_devlink yet
- disable the legacy GPIO character device uAPI v1 supprt in Kconfig
by default
- rework several core functions in preparation for the upcoming
Revocable helper library for protecting resources against sudden
removal, this reduces the number of SRCU dereferences in GPIO core
- simplify file descriptor logic in GPIO character device code by
using FD_PREPARE()
- introduce a header defining symbols used by both GPIO consumers and
providers to avoid having to include provider-specific headers from
drivers which only consume GPIOs
- replace snprintf() with strscpy() where formatting is not required
New drivers:
- add the gpio-by-pinctrl generic driver using the ARM SCMI protocol
to control GPIOs (along with SCMI changes pulled from the pinctrl
tree)
- add a driver providing support for handling of platform events via
GPIO-signalled ACPI events (used on Intel Nova Lake and later
platforms)
Driver changes:
- extend the gpio-kempld driver with support for more recent models,
interrupts and setting/getting multiple values at once
- improve interrupt handling in gpio-brcmstb
- add support for multi-SoC systems in gpio-tegra186
- make sure we return correct values from the .get() callbacks in
several GPIO drivers by normalizing any values other than 0, 1 or
negative error numbers
- use flexible arrays in several drivers to reduce the number of
required memory allocations
- simplify synchronous waiting for virtual drivers to probe and
remove the dedicated, a bit overengineered helper library
dev-sync-probe
- remove unneeded Kconfig dependencies on OF_GPIO in several drivers
and subsystems
- convert the two remaining users of of_get_named_gpio() to using
GPIO descriptors and remove the (no longer used) function along
with the header that declares it
- add missing includes in gpio-mmio
- shrink and simplify code in gpio-max732x by using guard(mutex)
- remove duplicated code handling the 'ngpios' property from
gpio-ts4800, it's already handled in GPIO core
- use correct variable type in gpio-aspeed
- add support for a new model in gpio-realtek-otto
- allow to specify the active-low setting of simulated hogs over the
configfs interface (in addition to existing devicetree support) in
gpio-sim
Bug fixes:
- clear the OF_POPULATED flag on hog nodes in GPIO chip remove path
on OF systems
- fix resource leaks in error path in gpiochip_add_data_with_key()
- drop redundant device reference in gpio-mpsse
Tests:
- add selftests for use-after-free cases in GPIO character device
code
DT bindings:
- add a DT binding document for SCMI based, gpio-over-pinctrl devices
- fix interrupt description in microchip,mpfs-gpio
- add new compatible for gpio-realtek-otto
- describe the resets of the mpfs-gpio controller
- fix maintainer's email in gpio-delay bindings
- remove the binding document for cavium,thunder-8890 as the
corresponding device is bound over PCI and not firmware nodes
Documentation:
- update the recommended way of converting legacy boards to using
software nodes for GPIO description
- describe GPIO line value semantics
- misc updates to kerneldocs
Misc:
- convert OMAP1 ams-delta board to using GPIO hogs described with
software nodes"
* tag 'gpio-updates-for-v7.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux: (79 commits)
gpio: swnode: defer probe on references to unregistered software nodes
dt-bindings: gpio: cavium,thunder-8890: Remove DT binding
Documentation: gpio: update the preferred method for using software node lookup
gpio: gpio-by-pinctrl: s/used to do/is used to do/
gpio: aspeed: fix unsigned long int declaration
gpio: rockchip: convert to dynamic GPIO base allocation
gpio: remove dev-sync-probe
gpio: virtuser: stop using dev-sync-probe
gpio: aggregator: stop using dev-sync-probe
gpio: sim: stop using dev-sync-probe
gpio: Add Intel Nova Lake ACPI GPIO events driver
gpiolib: Make deferral warnings debug messages
gpiolib: fix hogs with multiple lines
gpio: fix up CONFIG_OF dependencies
gpio: gpio-by-pinctrl: add pinctrl based generic GPIO driver
gpio: dt-bindings: Add GPIO on top of generic pin control
firmware: arm_scmi: Allow PINCTRL_REQUEST to return EOPNOTSUPP
pinctrl: scmi: ignore PIN_CONFIG_PERSIST_STATE
pinctrl: scmi: Delete PIN_CONFIG_OUTPUT_IMPEDANCE_OHMS support
pinctrl: scmi: Add SCMI_PIN_INPUT_VALUE
...
Diffstat (limited to 'Documentation/driver-api')
| -rw-r--r-- | Documentation/driver-api/gpio/board.rst | 39 | ||||
| -rw-r--r-- | Documentation/driver-api/gpio/driver.rst | 27 | ||||
| -rw-r--r-- | Documentation/driver-api/gpio/legacy-boards.rst | 36 |
3 files changed, 72 insertions, 30 deletions
diff --git a/Documentation/driver-api/gpio/board.rst b/Documentation/driver-api/gpio/board.rst index 069b54d8591b..4ac1e12cf872 100644 --- a/Documentation/driver-api/gpio/board.rst +++ b/Documentation/driver-api/gpio/board.rst @@ -108,9 +108,8 @@ macro, which ties a software node representing the GPIO controller with consumer device. It allows consumers to use regular gpiolib APIs, such as gpiod_get(), gpiod_get_optional(). -The software node representing a GPIO controller need not be attached to the -GPIO controller device. The only requirement is that the node must be -registered and its name must match the GPIO controller's label. +The software node representing a GPIO controller must be attached to the +GPIO controller device - either as the primary or the secondary firmware node. For example, here is how to describe a single GPIO-connected LED. This is an alternative to using platform_data on legacy systems. @@ -122,8 +121,7 @@ alternative to using platform_data on legacy systems. #include <linux/gpio/property.h> /* - * 1. Define a node for the GPIO controller. Its .name must match the - * controller's label. + * 1. Define a node for the GPIO controller. */ static const struct software_node gpio_controller_node = { .name = "gpio-foo", @@ -153,6 +151,21 @@ alternative to using platform_data on legacy systems. }; software_node_register_node_group(swnodes); + /* + * 5. Attach the GPIO controller's software node to the device and + * register it. + */ + static void gpio_foo_register(void) + { + struct platform_device_info pdev_info = { + .name = "gpio-foo", + .id = PLATFORM_DEVID_NONE, + .swnode = &gpio_controller_node + }; + + platform_device_register_full(&pdev_info); + } + // Then register a platform_device for "leds-gpio" and associate // it with &led_device_swnode via .fwnode. @@ -239,22 +252,6 @@ mapping and is thus transparent to GPIO consumers. A set of functions such as gpiod_set_value() is available to work with the new descriptor-oriented interface. -Boards using platform data can also hog GPIO lines by defining GPIO hog tables. - -.. code-block:: c - - struct gpiod_hog gpio_hog_table[] = { - GPIO_HOG("gpio.0", 10, "foo", GPIO_ACTIVE_LOW, GPIOD_OUT_HIGH), - { } - }; - -And the table can be added to the board code as follows:: - - gpiod_add_hogs(gpio_hog_table); - -The line will be hogged as soon as the gpiochip is created or - in case the -chip was created earlier - when the hog table is registered. - Arrays of pins -------------- In addition to requesting pins belonging to a function one by one, a device may diff --git a/Documentation/driver-api/gpio/driver.rst b/Documentation/driver-api/gpio/driver.rst index 85d86f92c41b..a4f160b95089 100644 --- a/Documentation/driver-api/gpio/driver.rst +++ b/Documentation/driver-api/gpio/driver.rst @@ -87,6 +87,33 @@ atomic context on realtime kernels (inside hard IRQ handlers and similar contexts). Normally this should not be required. +GPIO level semantics +-------------------- + +The gpip_chip .get/set[_multiple]() line values are clamped to the boolean +space [0, 1], low level or high level. + +Low and high values are defined as physical low on the line in/out to the +connector such as a physical pad, pin or rail. + +The GPIO library has internal logic to handle lines that are active low, such +as indicated by overstrike or #name in a schematic, and the driver should not +try to second-guess the logic value of a line. + +The way GPIO values are handled by the consumers is that the library present +the *logical* value to the consumer. A line is *asserted* if its *logical* +value is 1, and *de-asserted* if its logical value is 0. If inversion is +required, this is handled by gpiolib and configured using hardware descriptions +such as device tree or ACPI that can clearly indicate if a line is active +high or low. + +Since electronics commonly insert inverters as driving stages or protection +buffers in front of a GPIO line it is necessary that this semantic is part +of the hardware description, so that consumers such as kernel drivers need +not worry about this, and can for example assert a RESET line tied to a GPIO +pin by setting it to logic 1 even if it is physically active low. + + GPIO electrical configuration ----------------------------- diff --git a/Documentation/driver-api/gpio/legacy-boards.rst b/Documentation/driver-api/gpio/legacy-boards.rst index 46e3a26dba77..a9d33bcbb176 100644 --- a/Documentation/driver-api/gpio/legacy-boards.rst +++ b/Documentation/driver-api/gpio/legacy-boards.rst @@ -36,12 +36,10 @@ Requirements for GPIO Properties When using software nodes to describe GPIO connections, the following requirements must be met for the GPIO core to correctly resolve the reference: -1. **The GPIO controller's software node "name" must match the controller's - "label".** The gpiolib core uses this name to find the corresponding - struct gpio_chip at runtime. - This software node has to be registered, but need not be attached to the - device representing the GPIO controller that is providing the GPIO in - question. It may be left as a "free floating" node. +1. **The GPIO controller's software node must be registered and attached to + the controller's ``struct device`` either as its primary or secondary + firmware node.** The gpiolib core uses the address of the firmware node to + find the corresponding ``struct gpio_chip`` at runtime. 2. **The GPIO property must be a reference.** The ``PROPERTY_ENTRY_GPIO()`` macro handles this as it is an alias for ``PROPERTY_ENTRY_REF()``. @@ -121,13 +119,21 @@ A typical legacy board file might look like this: /* Device registration */ static int __init myboard_init(void) { + struct platform_device_info pdev_info = { + .name = MYBOARD_GPIO_CONTROLLER, + .id = PLATFORM_DEVID_NONE, + .swnode = &gpio_controller_node + }; + gpiod_add_lookup_table(&myboard_leds_gpios); gpiod_add_lookup_table(&myboard_buttons_gpios); + platform_device_register_full(&pdev_info); platform_device_register_data(NULL, "leds-gpio", -1, &myboard_leds_pdata, sizeof(myboard_leds_pdata)); platform_device_register_data(NULL, "gpio-keys", -1, - &myboard_buttons_pdata, sizeof(myboard_buttons_pdata)); + &myboard_buttons_pdata, + sizeof(myboard_buttons_pdata)); return 0; } @@ -141,8 +147,7 @@ Step 1: Define the GPIO Controller Node *************************************** First, define a software node that represents the GPIO controller that the -LEDs and buttons are connected to. The ``name`` of this node must match the -name of the driver for the GPIO controller (e.g., "gpio-foo"). +LEDs and buttons are connected to. The ``name`` of this node is optional. .. code-block:: c @@ -258,12 +263,23 @@ software nodes using the ``fwnode`` field in struct platform_device_info. return error; memset(&pdev_info, 0, sizeof(pdev_info)); + pdev_info.name = MYBOARD_GPIO_CONTROLLER; + pdev_info.id = PLATFORM_DEVID_NONE; + pdev_info.swnode = &myboard_gpio_controller_node; + gpio_pdev = platform_device_register_full(&pdev_info); + if (IS_ERR(gpio_pdev)) { + error = PTR_ERR(gpio_pdev); + goto err_unregister_nodes; + } + + memset(&pdev_info, 0, sizeof(pdev_info)); pdev_info.name = "leds-gpio"; pdev_info.id = PLATFORM_DEVID_NONE; pdev_info.fwnode = software_node_fwnode(&myboard_leds_node); leds_pdev = platform_device_register_full(&pdev_info); if (IS_ERR(leds_pdev)) { error = PTR_ERR(leds_pdev); + platform_device_unregister(gpio_pdev); goto err_unregister_nodes; } @@ -274,6 +290,7 @@ software nodes using the ``fwnode`` field in struct platform_device_info. keys_pdev = platform_device_register_full(&pdev_info); if (IS_ERR(keys_pdev)) { error = PTR_ERR(keys_pdev); + platform_device_unregister(gpio_pdev); platform_device_unregister(leds_pdev); goto err_unregister_nodes; } @@ -289,6 +306,7 @@ software nodes using the ``fwnode`` field in struct platform_device_info. { platform_device_unregister(keys_pdev); platform_device_unregister(leds_pdev); + platform_device_unregister(gpio_pdev); software_node_unregister_node_group(myboard_swnodes); } |
