Age | Commit message (Collapse) | Author |
|
Call gpio_aggregator_free_lines() before returning on this error path.
Fixes: 83c8e3df642f ("gpio: aggregator: expose aggregator created via legacy sysfs to configfs")
Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
Acked-by: Koichiro Den <koichiro.den@canonical.com>
Link: https://lore.kernel.org/r/e023bfe52509ce1bef6209ec7c47e99279c551dd.1744452787.git.dan.carpenter@linaro.org
Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
|
|
Propagate the error code if gpio_aggregator_make_device_sw_node() fails.
Don't return success.
Fixes: 86f162e73d2d ("gpio: aggregator: introduce basic configfs interface")
Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
Acked-by: Koichiro Den <koichiro.den@canonical.com>
Link: https://lore.kernel.org/r/79b804a0769a434698616bebedacc0e5d5605fdc.1744452787.git.dan.carpenter@linaro.org
Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
|
|
gpio_aggregator_parse()
The error handling in gpio_aggregator_parse() was re-written. It now
returns success if there are no GPIOs. Restore the previous behavior
and return -EINVAL instead.
Fixes: 83c8e3df642f ("gpio: aggregator: expose aggregator created via legacy sysfs to configfs")
Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
Acked-by: Koichiro Den <koichiro.den@canonical.com>
Link: https://lore.kernel.org/r/9dcd5fda7a3819e896d9eee4156e7c46c9a64595.1744452787.git.dan.carpenter@linaro.org
Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
|
|
The gpio_aggregator_line_alloc() function returns error pointers, but
the callers check for NULL. Update the error checking in the callers.
Fixes: 83c8e3df642f ("gpio: aggregator: expose aggregator created via legacy sysfs to configfs")
Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
Acked-by: Koichiro Den <koichiro.den@canonical.com>
Link: https://lore.kernel.org/r/cc71d8cf6e9bb4bb8cd9ae5050100081891d9345.1744452787.git.dan.carpenter@linaro.org
Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
|
|
This code is intended to reject strings that start with "_sysfs" but the
strcmp() limit is wrong so checks the whole string instead of the prefix.
Fixes: 83c8e3df642f ("gpio: aggregator: expose aggregator created via legacy sysfs to configfs")
Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Koichiro Den <koichiro.den@canonical.com>
Link: https://lore.kernel.org/r/30210ed77b40b4b6629de659cb56b9ec7832c447.1744452787.git.dan.carpenter@linaro.org
Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
|
|
For aggregators initialized via configfs, write 1 to 'live' waits for
probe completion and returns an error if the probe fails, unlike the
legacy sysfs interface, which is asynchronous.
Since users control the liveness of the aggregator device and might be
editing configurations while 'live' is 0, deferred probing is both
unnatural and unsafe.
Cancel deferred probe for purely configfs-based aggregators when probe
fails.
Signed-off-by: Koichiro Den <koichiro.den@canonical.com>
Link: https://lore.kernel.org/r/20250407043019.4105613-8-koichiro.den@canonical.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
|
|
Expose settings for aggregators created using the sysfs 'new_device'
interface to configfs. Once written to 'new_device', an "_sysfs.<N>" path
appears in the configfs regardless of whether the probe succeeds.
Consequently, users can no longer use that prefix for custom GPIO
aggregator names. The 'live' attribute changes to 1 when the probe
succeeds and the GPIO forwarder is instantiated.
Note that the aggregator device created via sysfs is asynchronous, i.e.
writing into 'new_device' returns without waiting for probe completion,
and the probe may succeed, fail, or eventually succeed via deferred
probe. Thus, the 'live' attribute may change from 0 to 1 asynchronously
without notice. So, editing key/offset/name while it's waiting for
deferred probe is prohibited.
The configfs auto-generation relies on create_default_group(), which
inherently prohibits rmdir(2). To align with the limitation, this commit
also prohibits mkdir(2) for them. When users want to change the number
of lines for an aggregator initialized via 'new_device', they need to
tear down the device using 'delete_device' and reconfigure it from
scratch. This does not break previous behavior; users of legacy sysfs
interface simply gain additional almost read-only configfs exposure.
Still, users can write to the 'live' attribute to toggle the device
unless it's waiting for deferred probe. So once probe succeeds, they can
deactivate it in the same manner as the devices initialized via
configfs.
Signed-off-by: Koichiro Den <koichiro.den@canonical.com>
Link: https://lore.kernel.org/r/20250407043019.4105613-7-koichiro.den@canonical.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
|
|
Rename the local variable 'name' in gpio_aggregator_parse() to 'key'
because struct gpio_aggregator_line now uses the 'name' field for the
custom line name and the local variable actually represents a 'key'.
This change prepares for the next but one commit.
No functional change.
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Koichiro Den <koichiro.den@canonical.com>
Link: https://lore.kernel.org/r/20250407043019.4105613-6-koichiro.den@canonical.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
|
|
The existing sysfs 'new_device' interface has several limitations:
* No way to determine when GPIO aggregator creation is complete.
* No way to retrieve errors when creating a GPIO aggregator.
* No way to trace a GPIO line of an aggregator back to its
corresponding physical device.
* The 'new_device' echo does not indicate which virtual gpiochip<N>
was created.
* No way to assign names to GPIO lines exported through an aggregator.
Introduce the new configfs interface for gpio-aggregator to address
these limitations. It provides a more streamlined, modern, and
extensible configuration method. For backward compatibility, the
'new_device' interface and its behavior is retained for now.
This commit implements basic functionalities:
/config/gpio-aggregator/<name-of-your-choice>/
/config/gpio-aggregator/<name-of-your-choice>/live
/config/gpio-aggregator/<name-of-your-choice>/dev_name
/config/gpio-aggregator/<name-of-your-choice>/<lineY>/
/config/gpio-aggregator/<name-of-your-choice>/<lineY>/key
/config/gpio-aggregator/<name-of-your-choice>/<lineY>/offset
/config/gpio-aggregator/<name-of-your-choice>/<lineY>/name
Basic setup flow is:
1. Create a directory for a GPIO aggregator.
2. Create subdirectories for each line you want to instantiate.
3. In each line directory, configure the key and offset.
The key/offset semantics are as follows:
* If offset is >= 0:
- key specifies the name of the chip this GPIO belongs to
- offset specifies the line offset within that chip.
* If offset is <0:
- key needs to specify the GPIO line name.
4. Return to the aggregator's root directory and write '1' to the live
attribute.
For example, the command in the existing kernel doc:
echo 'e6052000.gpio 19 e6050000.gpio 20-21' > new_device
is equivalent to:
mkdir /sys/kernel/config/gpio-aggregator/<custom-name>
# Change <custom-name> to name of your choice (e.g. "aggr0")
cd /sys/kernel/config/gpio-aggregator/<custom-name>
mkdir line0 line1 line2 # Only "line<Y>" naming allowed.
echo e6052000.gpio > line0/key
echo 19 > line0/offset
echo e6050000.gpio > line1/key
echo 20 > line1/offset
echo e6050000.gpio > line2/key
echo 21 > line2/offset
echo 1 > live
The corresponding gpio_device id can be identified as follows:
cd /sys/kernel/config/gpio-aggregator/<custom-name>
ls -d /sys/devices/platform/`cat dev_name`/gpiochip*
Also, via configfs, custom GPIO line name can be set like this:
cd /sys/kernel/config/gpio-aggregator/<custom-name>
echo "abc" > line1/name
Signed-off-by: Koichiro Den <koichiro.den@canonical.com>
Link: https://lore.kernel.org/r/20250407043019.4105613-5-koichiro.den@canonical.com
[Bartosz: remove stray newlines]
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
|
|
Prepare for the upcoming configfs interface. These functions will be
used by both the existing sysfs interface and the new configfs
interface, reducing code duplication.
No functional change.
Signed-off-by: Koichiro Den <koichiro.den@canonical.com>
Link: https://lore.kernel.org/r/20250407043019.4105613-4-koichiro.den@canonical.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
|
|
Unify function names to use gpio_aggregator_ prefix (except GPIO
forwarder implementations, which remain unchanged in subsequent
commits). While at it, rename the pre-existing gpio_aggregator_free() to
gpio_aggregator_destory(), since that name will be used by new
alloc/free functions introduced in the next commit, for which the name
is more appropriate.
No functional change.
Signed-off-by: Koichiro Den <koichiro.den@canonical.com>
Link: https://lore.kernel.org/r/20250407043019.4105613-3-koichiro.den@canonical.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
|
|
Reorder functions in drivers/gpio/gpio-aggregator.c to prepare for the
configfs-based interface additions in subsequent commits. Arrange the
code so that the configfs implementations will appear above the existing
sysfs-specific code, since the latter will partly depend on the configfs
interface implementations when it starts to expose the settings to
configfs.
The order in drivers/gpio/gpio-aggregator.c will be as follows:
* Basic gpio_aggregator/gpio_aggregator_line representations
* Common utility functions
* GPIO Forwarder implementations
* Configfs interface implementations
* Sysfs interface implementations
* Platform device implementations
* Module init/exit implementations
This separate commit ensures a clean diff for the subsequent commits.
No functional change.
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Koichiro Den <koichiro.den@canonical.com>
Link: https://lore.kernel.org/r/20250407043019.4105613-2-koichiro.den@canonical.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
|
|
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux into gpio/for-next
Linux 6.14-rc7
|
|
Both new_device_store and delete_device_store touch module global
resources (e.g. gpio_aggregator_lock). To prevent race conditions with
module unload, a reference needs to be held.
Add try_module_get() in these handlers.
For new_device_store, this eliminates what appears to be the most dangerous
scenario: if an id is allocated from gpio_aggregator_idr but
platform_device_register has not yet been called or completed, a concurrent
module unload could fail to unregister/delete the device, leaving behind a
dangling platform device/GPIO forwarder. This can result in various issues.
The following simple reproducer demonstrates these problems:
#!/bin/bash
while :; do
# note: whether 'gpiochip0 0' exists or not does not matter.
echo 'gpiochip0 0' > /sys/bus/platform/drivers/gpio-aggregator/new_device
done &
while :; do
modprobe gpio-aggregator
modprobe -r gpio-aggregator
done &
wait
Starting with the following warning, several kinds of warnings will appear
and the system may become unstable:
------------[ cut here ]------------
list_del corruption, ffff888103e2e980->next is LIST_POISON1 (dead000000000100)
WARNING: CPU: 1 PID: 1327 at lib/list_debug.c:56 __list_del_entry_valid_or_report+0xa3/0x120
[...]
RIP: 0010:__list_del_entry_valid_or_report+0xa3/0x120
[...]
Call Trace:
<TASK>
? __list_del_entry_valid_or_report+0xa3/0x120
? __warn.cold+0x93/0xf2
? __list_del_entry_valid_or_report+0xa3/0x120
? report_bug+0xe6/0x170
? __irq_work_queue_local+0x39/0xe0
? handle_bug+0x58/0x90
? exc_invalid_op+0x13/0x60
? asm_exc_invalid_op+0x16/0x20
? __list_del_entry_valid_or_report+0xa3/0x120
gpiod_remove_lookup_table+0x22/0x60
new_device_store+0x315/0x350 [gpio_aggregator]
kernfs_fop_write_iter+0x137/0x1f0
vfs_write+0x262/0x430
ksys_write+0x60/0xd0
do_syscall_64+0x6c/0x180
entry_SYSCALL_64_after_hwframe+0x76/0x7e
[...]
</TASK>
---[ end trace 0000000000000000 ]---
Fixes: 828546e24280 ("gpio: Add GPIO Aggregator")
Cc: stable@vger.kernel.org
Signed-off-by: Koichiro Den <koichiro.den@canonical.com>
Link: https://lore.kernel.org/r/20250224143134.3024598-2-koichiro.den@canonical.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
|
|
struct gpio_chip now has additional variants of the set(_multiple)
driver callbacks that return an integer to indicate success or failure.
Convert the driver to using them.
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Acked-by: Uwe Kleine-König <u.kleine-koenig@baylibre.com>
Link: https://lore.kernel.org/r/20250220-gpio-set-retval-v2-10-bc4cfd38dae3@linaro.org
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
|
|
The bitmap allocated in aggr_parse() is always freed before the function
returns so use __free(bitmap) to simplify it and drop the goto label.
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://lore.kernel.org/r/20240930163207.80276-1-brgl@bgdev.pl
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
|
|
The aggregator mode can also handle properties of the platform,
that do not belong to the GPIO controller itself. One of such
a property is a signal delay line. Set up a parser to support it.
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Tested-by: Alexander Stein <alexander.stein@ew.tq-group.com>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
|
|
In some cases the GPIO may require an additional delay after setting
its value. Add support for that into the GPIO forwarder code.
This will be fully enabled for use in the following changes.
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Tested-by: Alexander Stein <alexander.stein@ew.tq-group.com>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
|
|
They stop the driver being used with ACPI PRP0001 and are something
I want to avoid being cut and paste into new drivers. Also include
mod_devicetable.h as we struct of_device_id is defined in there.
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Tested-by: Alexander Stein <alexander.stein@ew.tq-group.com>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
|
|
Do not imply that some of the generic headers may be always included.
Instead, include explicitly what we are direct user of.
While at it, drop unused linux/gpio.h and split out the GPIO group of
headers.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
|
|
ARCH_NR_GPIOS is used locally in aggr_parse() as the maximum number
of GPIOs to be aggregated together by the driver since
commit ec75039d5550 ("gpio: aggregator: Use bitmap_parselist() for
parsing GPIO offsets").
Don't rely on the total possible number of GPIOs in the system but
define a local arbitrary macro for that, set to 512 which should be
large enough as it is also the default value for ARCH_NR_GPIOS.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
|
|
If the parent GPIO controller is a sleeping controller (e.g. a GPIO
controller connected to I2C), getting or setting a GPIO triggers a
might_sleep() warning. This happens because the GPIO Aggregator takes
the can_sleep flag into account only for its internal locking, not for
calling into the parent GPIO controller.
Fix this by using the gpiod_[gs]et*_cansleep() APIs when calling into a
sleeping GPIO controller.
Reported-by: Mikko Salomäki <ms@datarespons.se>
Fixes: 828546e24280f721 ("gpio: Add GPIO Aggregator")
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
|
|
Currently the GPIO Aggregator does not support interrupts. This means
that kernel drivers going from a GPIO to an IRQ using gpiod_to_irq(),
and userspace applications using line events do not work.
Add interrupt support by providing a gpio_chip.to_irq() callback, which
just calls into the parent GPIO controller.
Note that this does not implement full interrupt controller (irq_chip)
support, so using e.g. gpio-keys with "interrupts" instead of "gpios"
still does not work.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
|
|
The tmp[] member of the gpiochip_fwd structure is used to store both the
temporary values bitmap and the desc pointers for operations on multiple
GPIOs. As both are arrays with sizes unknown at compile-time, accessing
them requires offset calculations, which are currently duplicated in
gpio_fwd_get_multiple() and gpio_fwd_set_multiple().
Introduce (a) accessors for both arrays and (b) a macro to calculate the
needed storage size. This confines the layout of the tmp[] member into
a single spot, to ease maintenance.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
|
|
cmdline library provides next_arg() helper to traverse over parameters
and their values given in command line. Replace custom approach in the driver
by it.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
|
|
Remove trailing comma in terminator entries to avoid potential
expanding an array behind it.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
|
|
Instead of doing it in place, convert GPIO_LOOKUP_IDX() and GPIO_HOG()
to be compund literals that's allow to use them as rvalue in assignments.
Due to above conversion, use compound literal from the header
in the gpio-aggregator.c.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
|
|
We already have a nice helper called get_options() which can be used
to validate the input format. Replace isrange() by using it.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
|
|
Sparse can't see locking scheme used in ->get_multiple() and
->set_multiple() callbacks.
CHECK .../drivers/gpio/gpio-aggregator.c
.../spinlock.h:409:9: warning: context imbalance in 'gpio_fwd_get_multiple' - unexpected unlock
.../spinlock.h:409:9: warning: context imbalance in 'gpio_fwd_set_multiple' - unexpected unlock
Refactor them to have better readability and make Sparse happy.
Code size impact is +52 bytes with arm-linux-gnueabihf-gcc 7.5.0.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
|
|
Replace the custom code to parse GPIO offsets and/or GPIO offset ranges
by a call to bitmap_parselist(), and an iteration over the returned bit
mask.
This should have no impact on the format of the configuration parameters
written to the "new_device" virtual file in sysfs.
Suggested-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://lore.kernel.org/r/20200701114212.8520-3-geert+renesas@glider.be
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
|
In get_arg(), the variable start is pre-initialized, but overwritten
again in the first statement. Rework the assignment to not rely on
pre-initialization, to make the code easier to read.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://lore.kernel.org/r/20200701114212.8520-2-geert+renesas@glider.be
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|
|
GPIO controllers are exported to userspace using /dev/gpiochip*
character devices. Access control to these devices is provided by
standard UNIX file system permissions, on an all-or-nothing basis:
either a GPIO controller is accessible for a user, or it is not.
Currently no mechanism exists to control access to individual GPIOs.
Hence add a GPIO driver to aggregate existing GPIOs, and expose them as
a new gpiochip.
This supports the following use cases:
- Aggregating GPIOs using Sysfs
This is useful for implementing access control, and assigning a set
of GPIOs to a specific user or virtual machine.
- Generic GPIO Driver
This is useful for industrial control, where it can provide
userspace access to a simple GPIO-operated device described in DT,
cfr. e.g. spidev for SPI-operated devices.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Tested-by: Eugeniu Rosca <erosca@de.adit-jv.com>
Reviewed-by: Eugeniu Rosca <erosca@de.adit-jv.com>
Link: https://lore.kernel.org/r/20200511145257.22970-5-geert+renesas@glider.be
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
|