projects/linux·commit 5143840c

Merge tag 'gpio-updates-for-v6.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux

5143840c · Linus Torvalds <[email protected]> · 2025-03-25 20:05:43 -07:00

Pull gpio updates from Bartosz Golaszewski:
 "There are no new drivers this time but several changes to the core
  GPIO framework and various driver updates.

  This release cycle, we're starting a relatively straightforward but
  tedious rework of the GPIO consumer API: for historical reasons, the
  gpiod_set_value() variants would return void. Not only that but the
  GPIO provider interface does not even allow drivers to return a value
  to GPIO core. This is because initial GPIO controllers would be MMIO
  based and could not fail. We've had I2C, SPI and USB controllers for
  years too but no way of indicating failures to callers.

  This changes the consumer interface, adds new provider callbacks and
  starts converting the drivers under drivers/gpio/ to using them. Once
  this gets upstream, we'll keep on converting GPIO drivers that live
  elsewhere and once there are no more users of the old callbacks, we'll
  remove them and rename the new ones to the previous name. I imagine
  the last step would happen in one sweeping change like what you did
  for the remove_new() -> remove() renaming.

  We've also addressed an issue where invalid return values from GPIO
  drivers would get propagated to user-space by adding some
  GPIO-core-level sanitization. Again: not a complex change but way
  overdue.

  Other than that: lots of driver and core refactoring, DT-bindings
  changes and some other minor changes like coding style fixes or header
  reordering.

  GPIO core:
   - add sanitization of return values of GPIO provider callbacks so
     that invalid ones don't get propagated to user-space
   - add new variants of the line setter callbacks for GPIO providers
     that return an integer and allow to indicate driver errors to the
     GPIO core
   - change the interface of all gpiod_set_value() variants to return an
     integer thus becoming able to indicate failures in the underlying
     layer to callers
   - drop unneeded ERR_CAST in gpiolib-acpi
   - use for_each_if() where applicable
   - provide gpiod_multi_set_value_cansleep() as a new, simpler
     interface to gpiod_set_array_value_cansleep() and use it across
     several drivers treewide
   - reduce the number of atomic reads of the descriptor flags in
     gpiolib debugfs code
   - simplify for_each_hwgpio_in_range() and
     for_each_requested_gpio_in_range()
   - add support for three-cell GPIO specifiers in GPIO OF code
   - don't build HTE (hardware timestamp engine) GPIO code with the HTE
     subsystem disabled in Kconfig
   - unduplicate calls to gpiod_direction_input_nonotify()
   - rework the handling of the valid_mask property of GPIO chips: don't
     allow drivers to set it as it should only be handled by GPIO core
     and start actually enforcing it in GPIO core for *all* drivers, not
     only the ones implementing a custom request() callback
   - get the `ngpios` property from the fwnode of the GPIO chip, not its
     device in order to handle multi-bank GPIO chips

  Driver improvements:
   - convert a part of the GPIO drivers under drivers/gpio/ to using the
     new value setter callbacks
   - convert several drivers to using automatic lock guards from
     cleanup.h
   - allow building gpio-bt8xx with COMPILE_TEST=y
   - refactor gpio-74x164 (use devres, cleanup helpers, __counted_by()
     and bits.h macros)
   - refactor gpio-latch (use generic device properties, lock guards and
     some local variables for better readability)
   - refactor gpio-xilinx (improve the usage of the bitmap API)
   - support multiple virtual GPIO controller instances in gpio-virtio
   - allow gpio-regmap to use the standard `ngpios` property from
     GPIOLIB
   - factor out the common code for synchronous probing of virtual GPIO
     devices into its own library
   - use str_enable_disable(), str_high_low() and other string helpers
     where applicable
   - extend the gpio-mmio abstraction layer to allow calling into the
     pinctrl back-end when setting direction
   - convert gpio-vf610 to using the gpio-mmio library
   - use more devres in gpio-adnp
   - add support for reset-gpios in gpio-pcf857x
   - add support for more models to gpio-loongson-64bit

  DT bindings:
   - add new compatibles to gpio-vf610 and gpio-loongson
   - add missing gpio-ranges property to gpio-mvebu
   - add reset-gpios to nxp,pcf8575
   - enable gpio-hog parsing in ast2400-gpio

  Misc:
   - coding style improvements
   - kerneldoc fixes
   - includes reordering
   - updates to the TODO list"

* tag 'gpio-updates-for-v6.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux: (119 commits)
  gpio: TODO: add an item to track reworking the sysfs interface
  gpio: TODO: add an item to track the conversion to the new value setters
  gpio: TODO: add delimiters between tasks for better readability
  gpio: TODO: remove the pinctrl integration task
  gpio: TODO: remove task duplication
  gpio: TODO: remove the item about the new debugfs interface
  gpio: da9055: use new line value setter callbacks
  gpio: da9052: use new line value setter callbacks
  gpio: cs5535: use new line value setter callbacks
  gpio: crystalcove: use new line value setter callbacks
  gpio: cros-ec: use new line value setter callbacks
  gpio: creg-snps: use new line value setter callbacks
  gpio: cgbc: use new line value setter callbacks
  gpio: bt8xx: use new line value setter callbacks
  gpio: bt8xx: use lock guards
  gpio: bt8xx: allow to build the module with COMPILE_TEST=y
  gpio: bd9571mwv: use new line value setter callbacks
  gpio: bd71828: use new line value setter callbacks
  gpio: bd71815: use new line value setter callbacks
  gpio: bcm-kona: use new line value setter callbacks
  ...
Commit
5143840cef6bb1ec4f334604ecc55130dd196fed
Parents
c07666e2 · af54a2fb

Merge commit. Changes below are compared with the first parent: c07666e2.

Changes

72 files changed · +1456 −1169

FileStatusAddDelContent
Documentation/devicetree/bindings/gpio/aspeed,ast2400-gpio.yamlmodified+6−0View file
Documentation/devicetree/bindings/gpio/gpio-mvebu.yamlmodified+10−0View file
Documentation/devicetree/bindings/gpio/gpio-vf610.yamlmodified+1−0View file
Documentation/devicetree/bindings/gpio/loongson,ls-gpio.yamlmodified+3−0View file
Documentation/devicetree/bindings/gpio/nxp,pcf8575.yamlmodified+37−0View file
drivers/gpio/Kconfigmodified+7−2View file
drivers/gpio/Makefilemodified+3−0View file
drivers/gpio/TODOmodified+33−56View file
drivers/gpio/dev-sync-probe.cadded+97−0View file
drivers/gpio/dev-sync-probe.hadded+25−0View file
drivers/gpio/gpio-74x164.cmodified+46−46View file
drivers/gpio/gpio-adnp.cmodified+59−79View file
drivers/gpio/gpio-adp5520.cmodified+7−5View file
drivers/gpio/gpio-adp5585.cmodified+6−4View file
drivers/gpio/gpio-aggregator.cmodified+24−14View file
drivers/gpio/gpio-altera-a10sr.cmodified+7−7View file
drivers/gpio/gpio-altera.cmodified+4−2View file
drivers/gpio/gpio-amd-fch.cmodified+4−3View file
drivers/gpio/gpio-amd8111.cmodified+4−2View file
drivers/gpio/gpio-arizona.cmodified+5−4View file
drivers/gpio/gpio-aspeed-sgpio.cmodified+34−52View file
drivers/gpio/gpio-aspeed.cmodified+42−66View file
drivers/gpio/gpio-bcm-kona.cmodified+22−47View file
drivers/gpio/gpio-bd71815.cmodified+6−9View file
drivers/gpio/gpio-bd71828.cmodified+6−9View file
drivers/gpio/gpio-bd9571mwv.cmodified+4−4View file
drivers/gpio/gpio-brcmstb.cmodified+2−1View file
drivers/gpio/gpio-bt8xx.cmodified+17−31View file
drivers/gpio/gpio-cgbc.cmodified+14−10View file
drivers/gpio/gpio-creg-snps.cmodified+5−5View file
drivers/gpio/gpio-cros-ec.cmodified+5−8View file
drivers/gpio/gpio-crystalcove.cmodified+8−7View file
drivers/gpio/gpio-cs5535.cmodified+4−2View file
drivers/gpio/gpio-da9052.cmodified+12−22View file
drivers/gpio/gpio-da9055.cmodified+5−9View file
drivers/gpio/gpio-davinci.cmodified+4−2View file
drivers/gpio/gpio-grgpio.cmodified+2−1View file
drivers/gpio/gpio-latch.cmodified+36−32View file
drivers/gpio/gpio-loongson-64bit.cmodified+51−4View file
drivers/gpio/gpio-max3191x.cmodified+7−11View file
drivers/gpio/gpio-max77650.cmodified+6−8View file
drivers/gpio/gpio-mmio.cmodified+29−8View file
drivers/gpio/gpio-mockup.cmodified+9−5View file
drivers/gpio/gpio-mvebu.cmodified+8−7View file
drivers/gpio/gpio-nomadik.cmodified+2−1View file
drivers/gpio/gpio-pca953x.cmodified+9−8View file
drivers/gpio/gpio-pcf857x.cmodified+27−2View file
drivers/gpio/gpio-rcar.cmodified+5−8View file
drivers/gpio/gpio-regmap.cmodified+44−29View file
drivers/gpio/gpio-sim.cmodified+21−77View file
drivers/gpio/gpio-stmpe.cmodified+3−3View file
drivers/gpio/gpio-vf610.cmodified+17−88View file
drivers/gpio/gpio-virtio.cmodified+15−14View file
drivers/gpio/gpio-virtuser.cmodified+10−63View file
drivers/gpio/gpio-wcove.cmodified+2−1View file
drivers/gpio/gpio-wm831x.cmodified+2−1View file
drivers/gpio/gpio-xilinx.cmodified+37−65View file
drivers/gpio/gpio-xra1403.cmodified+2−1View file
drivers/gpio/gpiolib-acpi.cmodified+1−1View file
drivers/gpio/gpiolib-of.cmodified+104−24View file
drivers/gpio/gpiolib.cmodified+270−95View file
drivers/gpio/gpiolib.hmodified+21−18View file
drivers/leds/leds-aw200xx.cmodified+1−1View file
drivers/mmc/core/pwrseq_simple.cmodified+1−2View file
drivers/mux/gpio.cmodified+1−3View file
drivers/phy/motorola/phy-mapphone-mdm6600.cmodified+1−3View file
include/drm/drm_util.hmodified+1−15View file
include/linux/gpio.hmodified+2−2View file
include/linux/gpio/consumer.hmodified+50−30View file
include/linux/gpio/driver.hmodified+64−28View file
include/linux/gpio/regmap.hmodified+2−2View file
include/linux/util_macros.hmodified+15−0View file

Only the first 600 diff lines are shown. Download the complete patch.

Documentation/devicetree/bindings/gpio/aspeed,ast2400-gpio.yaml

View file
diff --git a/Documentation/devicetree/bindings/gpio/aspeed,ast2400-gpio.yaml b/Documentation/devicetree/bindings/gpio/aspeed,ast2400-gpio.yaml
index b9afd07..b16273e 100644
--- a/Documentation/devicetree/bindings/gpio/aspeed,ast2400-gpio.yaml
+++ b/Documentation/devicetree/bindings/gpio/aspeed,ast2400-gpio.yaml
@@ -46,6 +46,12 @@ properties:
minimum: 12
maximum: 232
+patternProperties:
+ "-hog(-[0-9]+)?$":
+ type: object
+ required:
+ - gpio-hog
+
required:
- compatible
- reg

Documentation/devicetree/bindings/gpio/gpio-mvebu.yaml

View file
diff --git a/Documentation/devicetree/bindings/gpio/gpio-mvebu.yaml b/Documentation/devicetree/bindings/gpio/gpio-mvebu.yaml
index 33d4e47..7ed5f9c 100644
--- a/Documentation/devicetree/bindings/gpio/gpio-mvebu.yaml
+++ b/Documentation/devicetree/bindings/gpio/gpio-mvebu.yaml
@@ -72,6 +72,9 @@ properties:
"#gpio-cells":
const: 2
+ gpio-ranges:
+ maxItems: 1
+
marvell,pwm-offset:
$ref: /schemas/types.yaml#/definitions/uint32
description: Offset in the register map for the pwm registers (in bytes)
@@ -96,6 +99,13 @@ properties:
- const: axi
minItems: 1
+patternProperties:
+ "^(.+-hog(-[0-9]+)?)$":
+ type: object
+
+ required:
+ - gpio-hog
+
required:
- compatible
- gpio-controller

Documentation/devicetree/bindings/gpio/gpio-vf610.yaml

View file
diff --git a/Documentation/devicetree/bindings/gpio/gpio-vf610.yaml b/Documentation/devicetree/bindings/gpio/gpio-vf610.yaml
index cabda2e..4fb32e9 100644
--- a/Documentation/devicetree/bindings/gpio/gpio-vf610.yaml
+++ b/Documentation/devicetree/bindings/gpio/gpio-vf610.yaml
@@ -28,6 +28,7 @@ properties:
- items:
- enum:
- fsl,imx93-gpio
+ - fsl,imx94-gpio
- fsl,imx95-gpio
- const: fsl,imx8ulp-gpio

Documentation/devicetree/bindings/gpio/loongson,ls-gpio.yaml

View file
diff --git a/Documentation/devicetree/bindings/gpio/loongson,ls-gpio.yaml b/Documentation/devicetree/bindings/gpio/loongson,ls-gpio.yaml
index cf3b1b2..b681596 100644
--- a/Documentation/devicetree/bindings/gpio/loongson,ls-gpio.yaml
+++ b/Documentation/devicetree/bindings/gpio/loongson,ls-gpio.yaml
@@ -20,7 +20,10 @@ properties:
- loongson,ls2k2000-gpio1
- loongson,ls2k2000-gpio2
- loongson,ls3a5000-gpio
+ - loongson,ls3a6000-gpio # Loongson-3A6000 node GPIO
- loongson,ls7a-gpio
+ - loongson,ls7a2000-gpio1 # LS7A2000 chipset GPIO
+ - loongson,ls7a2000-gpio2 # LS7A2000 ACPI GPIO
- items:
- const: loongson,ls2k1000-gpio
- const: loongson,ls2k-gpio

Documentation/devicetree/bindings/gpio/nxp,pcf8575.yaml

View file
diff --git a/Documentation/devicetree/bindings/gpio/nxp,pcf8575.yaml b/Documentation/devicetree/bindings/gpio/nxp,pcf8575.yaml
index 3718103..8bca574 100644
--- a/Documentation/devicetree/bindings/gpio/nxp,pcf8575.yaml
+++ b/Documentation/devicetree/bindings/gpio/nxp,pcf8575.yaml
@@ -73,6 +73,43 @@ properties:
wakeup-source: true
+ reset-gpios:
+ maxItems: 1
+ description:
+ GPIO controlling the (reset active LOW) RESET# pin.
+
+ The active polarity of the GPIO must translate to the low state of the
+ RESET# pin on the IC, i.e. if a GPIO is directly routed to the RESET# pin
+ without any inverter, GPIO_ACTIVE_LOW is expected.
+
+ Performing a reset makes all lines initialized to their input (pulled-up)
+ state.
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ not:
+ contains:
+ enum:
+ - nxp,pca9670
+ - nxp,pca9671
+ - nxp,pca9672
+ - nxp,pca9673
+ then:
+ properties:
+ reset-gpios: false
+
+ # lines-initial-states XOR reset-gpios
+ # Performing a reset reinitializes all lines to a known state which
+ # may not match passed lines-initial-states
+ - if:
+ required:
+ - lines-initial-states
+ then:
+ properties:
+ reset-gpios: false
+
patternProperties:
"^(.+-hog(-[0-9]+)?)$":
type: object

drivers/gpio/Kconfig

View file
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 98b4d16..f2c39bb 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -757,6 +757,7 @@ config GPIO_VF610
default y if SOC_VF610
depends on ARCH_MXC || COMPILE_TEST
select GPIOLIB_IRQCHIP
+ select GPIO_GENERIC
help
Say yes here to support i.MX or Vybrid vf610 GPIOs.
@@ -1670,7 +1671,7 @@ config GPIO_AMD8111
config GPIO_BT8XX
tristate "BT8XX GPIO abuser"
- depends on VIDEO_BT848=n
+ depends on VIDEO_BT848=n || COMPILE_TEST
help
The BT8xx frame grabber chip has 24 GPIO pins that can be abused
as a cheap PCI GPIO card.
@@ -1791,7 +1792,6 @@ menu "SPI GPIO expanders"
config GPIO_74X164
tristate "74x164 serial-in/parallel-out 8-bits shift register"
- depends on OF_GPIO
help
Driver for 74x164 compatible serial-in/parallel-out 8-outputs
shift registers. This driver can be used to provide access
@@ -1911,6 +1911,7 @@ config GPIO_SIM
tristate "GPIO Simulator Module"
select IRQ_SIM
select CONFIGFS_FS
+ select DEV_SYNC_PROBE
help
This enables the GPIO simulator - a configfs-based GPIO testing
driver.
@@ -1939,6 +1940,7 @@ config GPIO_VIRTUSER
select DEBUG_FS
select CONFIGFS_FS
select IRQ_WORK
+ select DEV_SYNC_PROBE
help
Say Y here to enable the configurable, configfs-based virtual GPIO
consumer testing driver.
@@ -1949,3 +1951,6 @@ config GPIO_VIRTUSER
endmenu
endif
+
+config DEV_SYNC_PROBE
+ tristate

drivers/gpio/Makefile

View file
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index af3ba4d..af13088 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -19,6 +19,9 @@ obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o
# directly supported by gpio-generic
gpio-generic-$(CONFIG_GPIO_GENERIC) += gpio-mmio.o
+# Utilities for drivers that need synchronous fake device creation
+obj-$(CONFIG_DEV_SYNC_PROBE) += dev-sync-probe.o
+
obj-$(CONFIG_GPIO_104_DIO_48E) += gpio-104-dio-48e.o
obj-$(CONFIG_GPIO_104_IDI_48) += gpio-104-idi-48.o
obj-$(CONFIG_GPIO_104_IDIO_16) += gpio-104-idio-16.o

drivers/gpio/TODO

View file
diff --git a/drivers/gpio/TODO b/drivers/gpio/TODO
index 942d1cd..b5f0a7a 100644
--- a/drivers/gpio/TODO
+++ b/drivers/gpio/TODO
@@ -1,6 +1,7 @@
This is a place for planning the ongoing long-term work in the GPIO
subsystem.
+===============================================================================
GPIO descriptors
@@ -48,6 +49,7 @@ Work items:
numberspace accessors from <linux/gpio.h> and eventually delete
<linux/gpio.h> altogether.
+-------------------------------------------------------------------------------
Get rid of <linux/of_gpio.h>
@@ -75,6 +77,7 @@ Work items:
- Delete <linux/of_gpio.h> when all the above is complete and everything
uses <linux/gpio/consumer.h> or <linux/gpio/driver.h> instead.
+-------------------------------------------------------------------------------
Get rid of <linux/gpio/legacy-of-mm-gpiochip.h>
@@ -85,15 +88,7 @@ Work items:
to_of_mm_gpio_chip(), of_mm_gpiochip_add_data(), of_mm_gpiochip_remove(),
CONFIG_OF_GPIO_MM_GPIOCHIP from the kernel.
-
-Get rid of <linux/gpio.h>
-
-This legacy header is a one stop shop for anything GPIO is closely tied
-to the global GPIO numberspace. The endgame of the above refactorings will
-be the removal of <linux/gpio.h> and from that point only the specialized
-headers under <linux/gpio/*.h> will be used. This requires all the above to
-be completed and is expected to take a long time.
-
+-------------------------------------------------------------------------------
Collect drivers
@@ -108,6 +103,7 @@ At the same time it makes sense to get rid of code duplication in existing or
new coming drivers. For example, gpio-ml-ioh should be incorporated into
gpio-pch.
+-------------------------------------------------------------------------------
Generic MMIO GPIO
@@ -128,6 +124,7 @@ Work items:
helpers (x86 inb()/outb()) and convert port-mapped I/O drivers to use
this with dry-coding and sending to maintainers to test
+-------------------------------------------------------------------------------
Generic regmap GPIO
@@ -135,6 +132,7 @@ In the very similar way to Generic MMIO GPIO convert the users which can
take advantage of using regmap over direct IO accessors. Note, even in
MMIO case the regmap MMIO with gpio-regmap.c is preferable over gpio-mmio.c.
+-------------------------------------------------------------------------------
GPIOLIB irqchip
@@ -144,53 +142,7 @@ try to cover any generic kind of irqchip cascaded from a GPIO.
- Look over and identify any remaining easily converted drivers and
dry-code conversions to gpiolib irqchip for maintainers to test
-
-Increase integration with pin control
-
-There are already ways to use pin control as back-end for GPIO and
-it may make sense to bring these subsystems closer. One reason for
-creating pin control as its own subsystem was that we could avoid any
-use of the global GPIO numbers. Once the above is complete, it may
-make sense to simply join the subsystems into one and make pin
-multiplexing, pin configuration, GPIO, etc selectable options in one
-and the same pin control and GPIO subsystem.
-
-
-Debugfs in place of sysfs
-
-The old sysfs code that enables simple uses of GPIOs from the
-command line is still popular despite the existance of the proper
-character device. The reason is that it is simple to use on
-root filesystems where you only have a minimal set of tools such
-as "cat", "echo" etc.
-
-The old sysfs still need to be strongly deprecated and removed
-as it relies on the global GPIO numberspace that assume a strict
-order of global GPIO numbers that do not change between boots
-and is independent of probe order.
-
-To solve this and provide an ABI that people can use for hacks
-and development, implement a debugfs interface to manipulate
-GPIO lines that can do everything that sysfs can do today: one
-directory per gpiochip and one file entry per line:
-
-/sys/kernel/debug/gpiochip/gpiochip0
-/sys/kernel/debug/gpiochip/gpiochip0/gpio0
-/sys/kernel/debug/gpiochip/gpiochip0/gpio1
-/sys/kernel/debug/gpiochip/gpiochip0/gpio2
-/sys/kernel/debug/gpiochip/gpiochip0/gpio3
-...
-/sys/kernel/debug/gpiochip/gpiochip1
-/sys/kernel/debug/gpiochip/gpiochip1/gpio0
-/sys/kernel/debug/gpiochip/gpiochip1/gpio1
-...
-
-The exact files and design of the debugfs interface can be
-discussed but the idea is to provide a low-level access point
-for debugging and hacking and to expose all lines without the
-need of any exporting. Also provide ample ammunition to shoot
-oneself in the foot, because this is debugfs after all.
-
+-------------------------------------------------------------------------------
Moving over to immutable irq_chip structures
@@ -209,3 +161,28 @@ A small number of drivers have been converted (pl061, tegra186, msm,
amd, apple), and can be used as examples of how to proceed with this
conversion. Note that drivers using the generic irqchip framework
cannot be converted yet, but watch this space!
+
+-------------------------------------------------------------------------------
+
+Convert all GPIO chips to using the new, value returning line setters
+
+struct gpio_chip's set() and set_multiple() callbacks are now deprecated. They
+return void and thus do not allow drivers to indicate failure to set the line
+value back to the caller.
+
+We've now added new variants - set_rv() and set_multiple_rv() that return an
+integer. Let's convert all GPIO drivers treewide to use the new callbacks,
+remove the old ones and finally rename the new ones back to the old names.
+
+-------------------------------------------------------------------------------
+
+Extend the sysfs ABI to allow exporting lines by their HW offsets
+
+The need to support the sysfs GPIO class is one of the main obstacles to
+removing the global GPIO numberspace from the kernel. In order to wean users
+off using global numbers from user-space, extend the existing interface with
+new per-gpiochip export/unexport attributes that allow to refer to GPIOs using
+their hardware offsets within the chip.
+
+Encourage users to switch to using them and eventually remove the existing
+global export/unexport attribues.

drivers/gpio/dev-sync-probe.c

View file
diff --git a/drivers/gpio/dev-sync-probe.c b/drivers/gpio/dev-sync-probe.c
new file mode 100644
index 0000000..9ea733b
--- /dev/null
+++ b/drivers/gpio/dev-sync-probe.c
@@ -0,0 +1,97 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Common code for drivers creating fake platform devices.
+ *
+ * Provides synchronous device creation: waits for probe completion and
+ * returns the probe success or error status to the device creator.
+ *
+ * Copyright (C) 2021 Bartosz Golaszewski <[email protected]>
+ * Copyright (C) 2025 Koichiro Den <[email protected]>
+ */
+
+#include <linux/device.h>
+#include <linux/slab.h>
+
+#include "dev-sync-probe.h"
+
+static int dev_sync_probe_notifier_call(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ struct dev_sync_probe_data *pdata;
+ struct device *dev = data;
+
+ pdata = container_of(nb, struct dev_sync_probe_data, bus_notifier);
+ if (!device_match_name(dev, pdata->name))
+ return NOTIFY_DONE;
+
+ switch (action) {
+ case BUS_NOTIFY_BOUND_DRIVER:
+ pdata->driver_bound = true;
+ break;
+ case BUS_NOTIFY_DRIVER_NOT_BOUND:
+ pdata->driver_bound = false;
+ break;
+ default:
+ return NOTIFY_DONE;
+ }
+
+ complete(&pdata->probe_completion);
+ return NOTIFY_OK;
+}
+
+void dev_sync_probe_init(struct dev_sync_probe_data *data)
+{
+ memset(data, 0, sizeof(*data));
+ init_completion(&data->probe_completion);
+ data->bus_notifier.notifier_call = dev_sync_probe_notifier_call;
+}
+EXPORT_SYMBOL_GPL(dev_sync_probe_init);
+
+int dev_sync_probe_register(struct dev_sync_probe_data *data,
+ struct platform_device_info *pdevinfo)
+{
+ struct platform_device *pdev;
+ char *name;
+
+ name = kasprintf(GFP_KERNEL, "%s.%d", pdevinfo->name, pdevinfo->id);
+ if (!name)
+ return -ENOMEM;
+
+ data->driver_bound = false;
+ data->name = name;
+ reinit_completion(&data->probe_completion);
+ bus_register_notifier(&platform_bus_type, &data->bus_notifier);
+
+ pdev = platform_device_register_full(pdevinfo);
+ if (IS_ERR(pdev)) {
+ bus_unregister_notifier(&platform_bus_type, &data->bus_notifier);
+ kfree(data->name);
+ return PTR_ERR(pdev);
+ }
+
+ wait_for_completion(&data->probe_completion);
+ bus_unregister_notifier(&platform_bus_type, &data->bus_notifier);
+
+ if (!data->driver_bound) {
+ platform_device_unregister(pdev);
+ kfree(data->name);
+ return -ENXIO;
+ }
+
+ data->pdev = pdev;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(dev_sync_probe_register);
+
+void dev_sync_probe_unregister(struct dev_sync_probe_data *data)
+{
+ platform_device_unregister(data->pdev);
+ kfree(data->name);
+ data->pdev = NULL;
+}
+EXPORT_SYMBOL_GPL(dev_sync_probe_unregister);
+
+MODULE_AUTHOR("Bartosz Golaszewski <[email protected]>");
+MODULE_AUTHOR("Koichiro Den <[email protected]>");
+MODULE_DESCRIPTION("Utilities for synchronous fake device creation");
+MODULE_LICENSE("GPL");

drivers/gpio/dev-sync-probe.h

View file
diff --git a/drivers/gpio/dev-sync-probe.h b/drivers/gpio/dev-sync-probe.h
new file mode 100644
index 0000000..4b3d52b
--- /dev/null
+++ b/drivers/gpio/dev-sync-probe.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef DEV_SYNC_PROBE_H
+#define DEV_SYNC_PROBE_H
+
+#include <linux/completion.h>
+#include <linux/notifier.h>
+#include <linux/platform_device.h>
+
+struct dev_sync_probe_data {
+ struct platform_device *pdev;
+ const char *name;
+
+ /* Synchronize with probe */
+ struct notifier_block bus_notifier;
+ struct completion probe_completion;
+ bool driver_bound;
+};
+
+void dev_sync_probe_init(struct dev_sync_probe_data *data);
+int dev_sync_probe_register(struct dev_sync_probe_data *data,
+ struct platform_device_info *pdevinfo);
+void dev_sync_probe_unregister(struct dev_sync_probe_data *data);
+
+#endif /* DEV_SYNC_PROBE_H */

drivers/gpio/gpio-74x164.c

View file
diff --git a/drivers/gpio/gpio-74x164.c b/drivers/gpio/gpio-74x164.c
index fca6cd2..4dd5c2c 100644
--- a/drivers/gpio/gpio-74x164.c
+++ b/drivers/gpio/gpio-74x164.c
@@ -7,6 +7,7 @@
*/
#include <linux/bitops.h>
+#include <linux/cleanup.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/driver.h>
#include <linux/module.h>
@@ -29,7 +30,7 @@ struct gen_74x164_chip {
* register at the end of the transfer. So, to have a logical
* numbering, store the bytes in reverse order.
*/
- u8 buffer[];
+ u8 buffer[] __counted_by(registers);
};
static int __gen_74x164_write_config(struct gen_74x164_chip *chip)
@@ -43,34 +44,31 @@ static int gen_74x164_get_value(struct gpio_chip *gc, unsigned offset)
struct gen_74x164_chip *chip = gpiochip_get_data(gc);
u8 bank = chip->registers - 1 - offset / 8;
u8 pin = offset % 8;
- int ret;
- mutex_lock(&chip->lock);
- ret = (chip->buffer[bank] >> pin) & 0x1;
- mutex_unlock(&chip->lock);
+ guard(mutex)(&chip->lock);
- return ret;
+ return !!(chip->buffer[bank] & BIT(pin));
}
-static void gen_74x164_set_value(struct gpio_chip *gc,
- unsigned offset, int val)
+static int gen_74x164_set_value(struct gpio_chip *gc,
+ unsigned int offset, int val)
{
struct gen_74x164_chip *chip = gpiochip_get_data(gc);
u8 bank = chip->registers - 1 - offset / 8;
u8 pin = offset % 8;
- mutex_lock(&chip->lock);
+ guard(mutex)(&chip->lock);
+
if (val)
- chip->buffer[bank] |= (1 << pin);
+ chip->buffer[bank] |= BIT(pin);
else
- chip->buffer[bank] &= ~(1 << pin);
+ chip->buffer[bank] &= ~BIT(pin);
- __gen_74x164_write_config(chip);
- mutex_unlock(&chip->lock);
+ return __gen_74x164_write_config(chip);
}
-static void gen_74x164_set_multiple(struct gpio_chip *gc, unsigned long *mask,
- unsigned long *bits)
+static int gen_74x164_set_multiple(struct gpio_chip *gc, unsigned long *mask,
+ unsigned long *bits)
{
struct gen_74x164_chip *chip = gpiochip_get_data(gc);
unsigned long offset;
@@ -78,7 +76,8 @@ static void gen_74x164_set_multiple(struct gpio_chip *gc, unsigned long *mask,
size_t bank;
unsigned long bitmask;
- mutex_lock(&chip->lock);
+ guard(mutex)(&chip->lock);
+
for_each_set_clump8(offset, bankmask, mask, chip->registers * 8) {
bank = chip->registers - 1 - offset / 8;
bitmask = bitmap_get_value8(bits, offset) & bankmask;
@@ -86,8 +85,7 @@ static void gen_74x164_set_multiple(struct gpio_chip *gc, unsigned long *mask,
chip->buffer[bank] &= ~bankmask;
chip->buffer[bank] |= bitmask;
}
- __gen_74x164_write_config(chip);
- mutex_unlock(&chip->lock);
+ return __gen_74x164_write_config(chip);
}
static int gen_74x164_direction_output(struct gpio_chip *gc,
@@ -97,8 +95,22 @@ static int gen_74x164_direction_output(struct gpio_chip *gc,
return 0;
}
+static void gen_74x164_deactivate(void *data)
+{
+ struct gen_74x164_chip *chip = data;
+
+ gpiod_set_value_cansleep(chip->gpiod_oe, 0);
+}
+
+static int gen_74x164_activate(struct device *dev, struct gen_74x164_chip *chip)
+{
+ gpiod_set_value_cansleep(chip->gpiod_oe, 1);
+ return devm_add_action_or_reset(dev, gen_74x164_deactivate, chip);
+}
+
static int gen_74x164_probe(struct spi_device *spi)
{
+ struct device *dev = &spi->dev;
struct gen_74x164_chip *chip;
u32 nregs;
int ret;
@@ -112,55 +124,44 @@ static int gen_74x164_probe(struct spi_device *spi)
if (ret < 0)
return ret;
- ret = device_property_read_u32(&spi->dev, "registers-number", &nregs);
- if (ret) {
- dev_err(&spi->dev, "Missing 'registers-number' property.\n");
- return -EINVAL;
- }
+ ret = device_property_read_u32(dev, "registers-number", &nregs);
+ if (ret)
+ return dev_err_probe(dev, ret, "Missing 'registers-number' property.\n");
- chip = devm_kzalloc(&spi->dev, sizeof(*chip) + nregs, GFP_KERNEL);
+ chip = devm_kzalloc(dev, struct_size(chip, buffer, nregs), GFP_KERNEL);
if (!chip)
return -ENOMEM;

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-adnp.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-adp5520.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-adp5585.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-aggregator.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-altera-a10sr.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-altera.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-amd-fch.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-amd8111.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-arizona.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-aspeed-sgpio.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-aspeed.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-bcm-kona.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-bd71815.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-bd71828.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-bd9571mwv.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-brcmstb.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-bt8xx.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-cgbc.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-creg-snps.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-cros-ec.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-crystalcove.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-cs5535.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-da9052.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-da9055.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-davinci.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-grgpio.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-latch.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-loongson-64bit.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-max3191x.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-max77650.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-mmio.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-mockup.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-mvebu.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-nomadik.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-pca953x.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-pcf857x.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-rcar.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-regmap.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-sim.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-stmpe.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-vf610.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-virtio.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-virtuser.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-wcove.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-wm831x.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-xilinx.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpio-xra1403.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpiolib-acpi.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpiolib-of.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpiolib.c

View file

This diff is incomplete. Download the complete patch.

drivers/gpio/gpiolib.h

View file

This diff is incomplete. Download the complete patch.

drivers/leds/leds-aw200xx.c

View file

This diff is incomplete. Download the complete patch.

drivers/mmc/core/pwrseq_simple.c

View file

This diff is incomplete. Download the complete patch.

drivers/mux/gpio.c

View file

This diff is incomplete. Download the complete patch.

drivers/phy/motorola/phy-mapphone-mdm6600.c

View file

This diff is incomplete. Download the complete patch.

include/drm/drm_util.h

View file

This diff is incomplete. Download the complete patch.

include/linux/gpio.h

View file

This diff is incomplete. Download the complete patch.

include/linux/gpio/consumer.h

View file

This diff is incomplete. Download the complete patch.

include/linux/gpio/driver.h

View file

This diff is incomplete. Download the complete patch.

include/linux/gpio/regmap.h

View file

This diff is incomplete. Download the complete patch.

include/linux/util_macros.h

View file

This diff is incomplete. Download the complete patch.