* Re: [PATCH v3] HID: Expose LattePanda IOTA UPS as a power_supply device
From: Benjamin Tissoires @ 2026-05-21 6:54 UTC (permalink / raw)
To: Andrew Maney; +Cc: jikos, linux-kernel, linux-input
In-Reply-To: <20260521031750.498110-1-andrewmaney05@gmail.com>
On May 20 2026, Andrew Maney wrote:
> This driver exposes the DFRobot LattePanda IOTA UPS board as a standard
> power_supply device, allowing desktop environments and power management
> tools such as UPower and systemd-logind to display battery status,
> remaining capacity, and charging status without any special
> configuration. It also enables automatic suspend or shutdown on low
> battery and power profile configuration via any tool that supports the
> standard power_supply interface.
>
> The UPS presents itself as an Arduino Leonardo HID device running custom
> firmware (VID 0x2341, PID 0x8036). It reports status and capacity via
> HID reports 0x07 and 0x0C respectively.
As sashiko detected, you are using a standard Arduino Leonardo and not
making any specific detections. So I was thinking that maybe we should
implement that feature as a HID-BPF program on top of the generic HID
handling.
However, the handling of battery supplies in the HID generic core is not
entirely filling all of the requirements here, but that's something I
wanted to do for a couple of month but I have been swamped with other
projects.
Anyway, I wanted to understand why this product was using a generic
Leonardo PID, and: https://wiki.dfrobot.com/dfr1247#tech_specs
"it leverages the standard HID-UPS protocol to be natively recognized by
Windows as a battery-powered device"
So. Instead of working on a custom driver, why not simply implement (or
finish the generic implementation) of HID-UPS in hid-input.c?
Cheers,
Benjamin
>
> The charge limit (80% or 100%) is configured via a physical DIP switch
> on the UPS board and cannot be detected automatically. Userspace can
> inform the driver of the configured limit via
> charge_control_end_threshold.
>
> ---
>
> Changes in v3:
> - Deferred power_supply registration to workqueue to avoid blocking probe
> - Fixed kernel panic when instantiated via uhid by checking hid_is_usb()
> before dereferencing USB-specific structures
>
> - Fixed ERR_PTR dereference in raw_event by only assigning ups->psu on
> successful registration
>
> - Fixed data race on ups->charge_limit using spin_lock_irqsave()
> - Removed TIME_TO_EMPTY_NOW and TIME_TO_FULL_NOW properties to avoid
> spurious shutdowns
>
> - Changed plugged-in but not charging state from FULL to NOT_CHARGING
> - Used devm_kasprintf() for a unique sysfs name in order to support
> multiple devices
>
> - Added POWER_SUPPLY and HIDRAW dependencies to Kconfig
> - Used %pe for more human-readable error messages
>
> Changes in v2:
> - Rebased on top of the current tree
> - Moved vendor and device IDs to drivers/hid/hid-ids.h
> - Added Kconfig entry under HID bus support -> Special HID drivers
> - Added build rule to drivers/hid/Makefile
>
> Signed-off-by: Andrew Maney <andrewmaney05@gmail.com>
> ---
> MAINTAINERS | 6 +
> drivers/hid/Kconfig | 10 +
> drivers/hid/Makefile | 1 +
> drivers/hid/hid-ids.h | 3 +
> drivers/hid/hid-lattepanda-iota-ups.c | 409 ++++++++++++++++++++++++++
> 5 files changed, 429 insertions(+)
> create mode 100644 drivers/hid/hid-lattepanda-iota-ups.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 10e825318..d80721c2c 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -11416,6 +11416,12 @@ F: include/uapi/linux/hid*
> F: samples/hid/
> F: tools/testing/selftests/hid/
>
> +HID LATTEPANDA IOTA UPS DRIVER
> +M: Andrew Maney <andrewmaney05@gmail.com>
> +L: linux-input@vger.kernel.org
> +S: Maintained
> +F: drivers/hid/hid-lattepanda-iota-ups.c
> +
> HID LOGITECH DRIVERS
> R: Filipe Laíns <lains@riseup.net>
> L: linux-input@vger.kernel.org
> diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
> index ff2f580b6..21ffc2fd0 100644
> --- a/drivers/hid/Kconfig
> +++ b/drivers/hid/Kconfig
> @@ -510,6 +510,16 @@ config HID_KYSONA
> Say Y here if you have a Kysona M600 mouse
> and want to be able to read its battery capacity.
>
> +config HID_LATTEPANDA_IOTA_UPS
> + tristate "LattePanda IOTA UPS"
> + depends on USB_HID && USB_HIDDEV && X86 && POWER_SUPPLY
> + help
> + Support for the LattePanda IOTA UPS (DFRobot, VID 0x2341 PID 0x8036).
> + Exposes the battery status and capacity via the power_supply interface.
> +
> + To compile as a module, choose M here: the module will be
> + called hid-lattepanda-iota-ups.
> +
> config HID_UCLOGIC
> tristate "UC-Logic"
> depends on USB_HID
> diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
> index 0597fd6a4..d7ad3fc8f 100644
> --- a/drivers/hid/Makefile
> +++ b/drivers/hid/Makefile
> @@ -74,6 +74,7 @@ obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o
> obj-$(CONFIG_HID_KEYTOUCH) += hid-keytouch.o
> obj-$(CONFIG_HID_KYE) += hid-kye.o
> obj-$(CONFIG_HID_KYSONA) += hid-kysona.o
> +obj-$(CONFIG_HID_LATTEPANDA_IOTA_UPS) += hid-lattepanda-iota-ups.o
> obj-$(CONFIG_HID_LCPOWER) += hid-lcpower.o
> obj-$(CONFIG_HID_LENOVO) += hid-lenovo.o
> obj-$(CONFIG_HID_LENOVO_GO) += hid-lenovo-go.o
> diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
> index 4657d96fb..6ded2c943 100644
> --- a/drivers/hid/hid-ids.h
> +++ b/drivers/hid/hid-ids.h
> @@ -859,6 +859,9 @@
> #define USB_DEVICE_ID_LD_HYBRID 0x2090
> #define USB_DEVICE_ID_LD_HEATCONTROL 0x20A0
>
> +#define USB_VENDOR_ID_LATTEPANDA_IOTA 0x2341
> +#define USB_DEVICE_ID_LATTEPANDA_IOTA_UPS 0x8036
> +
> #define USB_VENDOR_ID_LENOVO 0x17ef
> #define USB_DEVICE_ID_LENOVO_TPKBD 0x6009
> #define USB_DEVICE_ID_LENOVO_CUSBKBD 0x6047
> diff --git a/drivers/hid/hid-lattepanda-iota-ups.c b/drivers/hid/hid-lattepanda-iota-ups.c
> new file mode 100644
> index 000000000..f5d522695
> --- /dev/null
> +++ b/drivers/hid/hid-lattepanda-iota-ups.c
> @@ -0,0 +1,409 @@
> +// SPDX-License-Identifier: GPL-2.0
> +#include <linux/power_supply.h>
> +#include <linux/completion.h>
> +#include <linux/workqueue.h>
> +#include <linux/module.h>
> +#include <linux/spinlock.h>
> +#include <linux/hid.h>
> +#include <linux/usb.h>
> +#include "hid-ids.h"
> +
> +#define REPORT_ID_CAPACITY 0x0C
> +#define REPORT_ID_STATUS 0x07
> +
> +#define STATUS_DISCHARGING BIT(1)
> +#define STATUS_PLUGGED_IN BIT(0)
> +#define STATUS_CHARGING BIT(2)
> +
> +MODULE_AUTHOR("Andrew Maney");
> +MODULE_DESCRIPTION("LattePanda IOTA UPS power supply driver");
> +MODULE_LICENSE("GPL");
> +
> +struct iota_ups {
> + struct power_supply_desc psu_desc;
> + struct power_supply *psu;
> + struct hid_device *hiddev;
> + spinlock_t lock; /* Protects cached HID report values */
> +
> + /* Cached values that are updated from HID reports */
> + bool plugged_in;
> + char serial[64];
> + int charge_limit;
> + int psu_status;
> + int capacity;
> +
> + /*
> + * Wait for both status and capacity reports before registering
> + * with the power_supply core, so initial values are correct and
> + * not erroneous.
> + */
> + struct completion got_initial_data;
> + struct work_struct register_work;
> + bool got_capacity;
> + bool data_ready;
> + bool got_status;
> +};
> +
> +static enum power_supply_property iota_ups_properties[] = {
> + POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD,
> + POWER_SUPPLY_PROP_SERIAL_NUMBER,
> + POWER_SUPPLY_PROP_MANUFACTURER,
> + POWER_SUPPLY_PROP_MODEL_NAME,
> + POWER_SUPPLY_PROP_TECHNOLOGY,
> + POWER_SUPPLY_PROP_CAPACITY,
> + POWER_SUPPLY_PROP_PRESENT,
> + POWER_SUPPLY_PROP_ONLINE,
> + POWER_SUPPLY_PROP_STATUS,
> + POWER_SUPPLY_PROP_SCOPE,
> +};
> +
> +static const struct hid_device_id iota_ups_devices[] = {
> + { HID_USB_DEVICE(USB_VENDOR_ID_LATTEPANDA_IOTA,
> + USB_DEVICE_ID_LATTEPANDA_IOTA_UPS) },
> + { }
> +};
> +MODULE_DEVICE_TABLE(hid, iota_ups_devices);
> +
> +static int iota_ups_get_property(struct power_supply *supply,
> + enum power_supply_property psp,
> + union power_supply_propval *val)
> +{
> + struct iota_ups *ups = power_supply_get_drvdata(supply);
> + unsigned long flags;
> +
> + spin_lock_irqsave(&ups->lock, flags);
> +
> + switch (psp) {
> + case POWER_SUPPLY_PROP_STATUS:
> + val->intval = ups->psu_status;
> + break;
> +
> + /* Remaining capacity as a percentage from 0 to 100 */
> + case POWER_SUPPLY_PROP_CAPACITY:
> + val->intval = ups->capacity;
> + break;
> +
> + /* The UPS is always present if the driver is loaded */
> + case POWER_SUPPLY_PROP_PRESENT:
> + val->intval = 1;
> + break;
> +
> + /* Whether mains power is connected */
> + case POWER_SUPPLY_PROP_ONLINE:
> + val->intval = ups->plugged_in ? 1 : 0;
> + break;
> +
> + /*
> + * The UPS board supplies power to the IOTA and any
> + * peripherals connected to it, therefore its scope
> + * is system-wide.
> + */
> + case POWER_SUPPLY_PROP_SCOPE:
> + val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
> + break;
> +
> + /* V1.0 only accepts 18650 Li-ion cells */
> + case POWER_SUPPLY_PROP_TECHNOLOGY:
> + val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
> + break;
> +
> + /* 80% or 100%, configured via a DIP switch on the UPS board */
> + case POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD:
> + val->intval = ups->charge_limit;
> + break;
> +
> + case POWER_SUPPLY_PROP_MANUFACTURER:
> + val->strval = "DFRobot";
> + break;
> +
> + case POWER_SUPPLY_PROP_MODEL_NAME:
> + val->strval = "LattePanda IOTA UPS";
> + break;
> +
> + /* Retrieved from the USB descriptor */
> + case POWER_SUPPLY_PROP_SERIAL_NUMBER:
> + val->strval = ups->serial;
> + break;
> +
> + default:
> + spin_unlock_irqrestore(&ups->lock, flags);
> + return -EINVAL;
> + }
> +
> + spin_unlock_irqrestore(&ups->lock, flags);
> + return 0;
> +}
> +
> +static int iota_ups_set_property(struct power_supply *supply,
> + enum power_supply_property psp,
> + const union power_supply_propval *val)
> +{
> + struct iota_ups *ups = power_supply_get_drvdata(supply);
> +
> + if (psp == POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD) {
> + unsigned long flags;
> +
> + /*
> + * V1.0 supports 80% and 100% charge limits only, which is
> + * set via a DIP switch on the board. This property allows
> + * userspace to inform the driver which limit is configured.
> + */
> + if (val->intval != 80 && val->intval != 100)
> + return -EINVAL;
> +
> + spin_lock_irqsave(&ups->lock, flags);
> + ups->charge_limit = val->intval;
> + spin_unlock_irqrestore(&ups->lock, flags);
> + return 0;
> + }
> +
> + return -EINVAL;
> +}
> +
> +static int iota_ups_property_is_writable(struct power_supply *supply,
> + enum power_supply_property psp)
> +{
> + return psp == POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD;
> +}
> +
> +static int iota_ups_raw_event(struct hid_device *hdev,
> + struct hid_report *report,
> + u8 *data, int size)
> +{
> + struct iota_ups *ups = hid_get_drvdata(hdev);
> + unsigned long flags;
> + bool changed = false;
> +
> + /* All of the UPS's reports are at least 2 bytes */
> + if (size < 2)
> + return 0;
> +
> + spin_lock_irqsave(&ups->lock, flags);
> +
> + switch (data[0]) {
> + case REPORT_ID_STATUS: {
> + u8 status = data[1];
> + int new_status;
> + bool plugged_in = !!(status & STATUS_PLUGGED_IN);
> +
> + /*
> + * The UPS status is determined as follows:
> + * Battery full:
> + * UPS is plugged in
> + * Battery is at full capacity
> + *
> + * Battery charging:
> + * UPS is plugged in
> + * Battery is not at full capacity
> + *
> + * Battery discharging:
> + * UPS is not plugged in
> + *
> + * Battery not charging:
> + * UPS is plugged in
> + * UPS has halted charging for some reason
> + *
> + * Unknown:
> + * None of the above conditions are met
> + */
> + if (status & STATUS_CHARGING) {
> + if (ups->capacity >= ups->charge_limit)
> + new_status = POWER_SUPPLY_STATUS_FULL;
> + else
> + new_status = POWER_SUPPLY_STATUS_CHARGING;
> +
> + } else if (status & STATUS_DISCHARGING) {
> + new_status = POWER_SUPPLY_STATUS_DISCHARGING;
> +
> + } else if (plugged_in) {
> + new_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
> +
> + } else {
> + new_status = POWER_SUPPLY_STATUS_UNKNOWN;
> + }
> +
> + if (new_status != ups->psu_status ||
> + plugged_in != ups->plugged_in) {
> + ups->plugged_in = plugged_in;
> + ups->psu_status = new_status;
> + changed = true;
> + }
> +
> + ups->got_status = true;
> + break;
> + }
> +
> + case REPORT_ID_CAPACITY: {
> + int new_cap = clamp((int)data[1], 0, 100);
> +
> + if (new_cap != ups->capacity) {
> + ups->capacity = new_cap;
> + changed = true;
> + }
> +
> + ups->got_capacity = true;
> + break;
> + }
> + }
> +
> + /*
> + * Signal that the UPS is ready to be registered because we have
> + * received both capacity and status reports.
> + */
> + if (!ups->data_ready && ups->got_status && ups->got_capacity) {
> + ups->data_ready = true;
> + complete(&ups->got_initial_data);
> + }
> +
> + spin_unlock_irqrestore(&ups->lock, flags);
> +
> + /*
> + * Notify the power_supply core outside the spinlock to avoid
> + * a deadlock; power_supply_changed() may call back into
> + * get_property() which acquires the same lock.
> + */
> + if (changed && ups->psu)
> + power_supply_changed(ups->psu);
> +
> + return 0;
> +}
> +
> +static void iota_ups_register_work(struct work_struct *work)
> +{
> + struct iota_ups *ups = container_of(work, struct iota_ups, register_work);
> + struct power_supply_config psu_config = {};
> + struct power_supply *psu;
> +
> + /*
> + * Wait for both status and capacity reports before registering.
> + * The device sends reports every ~1 second, so 3 seconds is safe.
> + * We wait here in order to prevent registration in an unknown
> + * state, since this could cause emergency shutdowns or other
> + * undesired effects.
> + */
> + wait_for_completion_timeout(&ups->got_initial_data,
> + msecs_to_jiffies(3000));
> +
> + /* Configure the UPS's power supply properties */
> + ups->psu_desc.name = devm_kasprintf(&ups->hiddev->dev, GFP_KERNEL,
> + "lattepanda-iota-ups.%s",
> + dev_name(&ups->hiddev->dev));
> +
> + if (!ups->psu_desc.name) {
> + hid_err(ups->hiddev, "failed to allocate power supply name\n");
> + return;
> + }
> +
> + ups->psu_desc.property_is_writeable = iota_ups_property_is_writable;
> + ups->psu_desc.num_properties = ARRAY_SIZE(iota_ups_properties);
> + ups->psu_desc.get_property = iota_ups_get_property;
> + ups->psu_desc.set_property = iota_ups_set_property;
> + ups->psu_desc.properties = iota_ups_properties;
> + ups->psu_desc.type = POWER_SUPPLY_TYPE_BATTERY;
> + psu_config.drv_data = ups;
> +
> + /* Register the UPS as a power_supply device */
> + psu = devm_power_supply_register(&ups->hiddev->dev, &ups->psu_desc, &psu_config);
> + if (IS_ERR(psu)) {
> + hid_err(ups->hiddev, "power supply registration failed: %pe\n", psu);
> + return;
> + }
> +
> + /*
> + * Finally, notify the power_supply core so userspace reads the correct
> + * initial state immediately after registration.
> + */
> + ups->psu = psu;
> + power_supply_changed(ups->psu);
> + hid_info(ups->hiddev, "LattePanda IOTA UPS registered as a power_supply device\n");
> +}
> +
> +static int iota_ups_probe(struct hid_device *hdev,
> + const struct hid_device_id *id)
> +{
> + struct iota_ups *ups;
> + int ret;
> +
> + ups = devm_kzalloc(&hdev->dev, sizeof(*ups), GFP_KERNEL);
> + if (!ups)
> + return -ENOMEM;
> +
> + ups->hiddev = hdev;
> + ups->psu_status = POWER_SUPPLY_STATUS_UNKNOWN;
> +
> + /* 50% is a safe default if wait_for_completion_timeout() times out. */
> + ups->capacity = 50;
> +
> + /*
> + * Default to 100% to prevent unexpected shutdowns.
> + * Userspace can update this via charge_control_end_threshold.
> + */
> + ups->charge_limit = 100;
> +
> + init_completion(&ups->got_initial_data);
> + spin_lock_init(&ups->lock);
> + hid_set_drvdata(hdev, ups);
> +
> + /*
> + * Retrieve the UPS's serial number from the USB descriptor. If the device is not
> + * a USB device, we can use the unique device identifier as the serial number.
> + */
> + if (hid_is_usb(hdev)) {
> + struct usb_device *udev = to_usb_device(hdev->dev.parent->parent);
> +
> + if (udev->serial)
> + strscpy(ups->serial, udev->serial, sizeof(ups->serial));
> + else
> + strscpy(ups->serial, "Unknown", sizeof(ups->serial));
> + } else {
> + if (*hdev->uniq)
> + strscpy(ups->serial, hdev->uniq, sizeof(ups->serial));
> + else
> + strscpy(ups->serial, "Unknown", sizeof(ups->serial));
> + }
> +
> + ret = hid_parse(hdev);
> + if (ret) {
> + hid_err(hdev, "HID parse failed: %pe\n", ERR_PTR(ret));
> + return ret;
> + }
> +
> + ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW);
> + if (ret) {
> + hid_err(hdev, "HID hw start failed: %pe\n", ERR_PTR(ret));
> + return ret;
> + }
> +
> + ret = hid_hw_open(hdev);
> + if (ret) {
> + hid_err(hdev, "HID hw open failed: %pe\n", ERR_PTR(ret));
> + goto err_stop;
> + }
> +
> + /* Probe for the UPS in a worker queue so we don't halt the enumeration thread */
> + INIT_WORK(&ups->register_work, iota_ups_register_work);
> + schedule_work(&ups->register_work);
> + return 0;
> +
> +err_stop:
> + hid_hw_stop(hdev);
> + return ret;
> +}
> +
> +static void iota_ups_remove(struct hid_device *hdev)
> +{
> + struct iota_ups *ups = hid_get_drvdata(hdev);
> +
> + cancel_work_sync(&ups->register_work);
> + hid_hw_close(hdev);
> + hid_hw_stop(hdev);
> +}
> +
> +static struct hid_driver iota_ups_driver = {
> + .name = "lattepanda-iota-ups",
> + .id_table = iota_ups_devices,
> + .probe = iota_ups_probe,
> + .remove = iota_ups_remove,
> + .raw_event = iota_ups_raw_event,
> +};
> +module_hid_driver(iota_ups_driver);
> --
> 2.54.0
>
>
^ permalink raw reply
* Re: [PATCH 04/10] [v2] sh: select legacy gpiolib interface
From: John Paul Adrian Glaubitz @ 2026-05-21 6:49 UTC (permalink / raw)
To: Arnd Bergmann, linux-gpio
Cc: linux-kernel, Arnd Bergmann, Christian Lamparter, Johannes Berg,
Aaro Koskinen, Andreas Kemnade, Kevin Hilman, Roger Quadros,
Tony Lindgren, Thomas Bogendoerfer, Thomas Gleixner, Ingo Molnar,
Borislav Petkov, Dave Hansen, x86, H. Peter Anvin, Linus Walleij,
Bartosz Golaszewski, Dmitry Torokhov, Lee Jones, Pavel Machek,
Matti Vaittinen, Florian Fainelli, Jonas Gorski, Andrew Lunn,
Vladimir Oltean, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, linux-wireless, linux-omap, linux-arm-kernel,
linux-mips, linux-sh, linux-input, linux-leds, netdev
In-Reply-To: <20260520183815.2510387-5-arnd@kernel.org>
Hi Arnd,
On Wed, 2026-05-20 at 20:38 +0200, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd@arndb.de>
>
> Many board files on sh reference the legacy gpiolib interfaces that
> are becoming optional. To ensure the boards can keep building, select
> CONFIG_GPIOLIB_LEGACY on each of the boards that have one of the
> hardcoded calls.
>
> Cc: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
> v2: no changes. Adrian said he'll pick it up for 7.2, but so
> far the patch is not in linux-next yet, so I'm including it
> for completeness here.
Sorry, I hadn't gotten around to pick the changes for v7.2 yet. I can
pick it up this weekend as I was planning to review and merge some
patches this weekend.
I have received quite a lot of patches for SH recently, so it will take
some time to dig myself through the queue.
Adrian
--
.''`. John Paul Adrian Glaubitz
: :' : Debian Developer
`. `' Physicist
`- GPG: 62FF 8A75 84E0 2956 9546 0006 7426 3B37 F5B5 F913
^ permalink raw reply
* Re: [PATCH v3] HID: Expose LattePanda IOTA UPS as a power_supply device
From: sashiko-bot @ 2026-05-21 3:45 UTC (permalink / raw)
To: Andrew Maney; +Cc: linux-input, dmitry.torokhov
In-Reply-To: <20260521031750.498110-1-andrewmaney05@gmail.com>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] The driver unconditionally binds to the generic Arduino Leonardo VID/PID, breaking standard HID input functionality for all such devices.
- [Medium] Device removal can block the USB disconnect process for up to 3 seconds if the device is unplugged during initialization.
- [Medium] The Kconfig dependency incorrectly requires `USB_HIDDEV`, preventing the driver from being built on modern systems.
- [Low] Unsynchronized access to the `ups->psu` pointer causes a C data race.
--
commit 9862889f837997957a0680fd4f3667a6d06c2828
Author: Andrew Maney <andrewmaney05@gmail.com>
HID: Expose LattePanda IOTA UPS as a power_supply device
This commit introduces a new HID driver to expose the LattePanda IOTA UPS
as a power_supply device. It reports battery status and capacity via HID
reports from a custom Arduino Leonardo firmware.
> diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
> index ff2f580b660ba..21ffc2fd06096 100644
> --- a/drivers/hid/Kconfig
> +++ b/drivers/hid/Kconfig
> @@ -510,6 +510,16 @@ config HID_KYSONA
> Say Y here if you have a Kysona M600 mouse
> and want to be able to read its battery capacity.
>
> +config HID_LATTEPANDA_IOTA_UPS
> + tristate "LattePanda IOTA UPS"
> + depends on USB_HID && USB_HIDDEV && X86 && POWER_SUPPLY
[Severity: Medium]
Does this driver actually require the legacy /dev/usb/hiddevX interface?
Since the driver connects using HID_CONNECT_HIDRAW, depending on USB_HIDDEV
could unnecessarily prevent the driver from being enabled or compiled on
distributions that have disabled legacy hiddev support.
> + help
> + Support for the LattePanda IOTA UPS (DFRobot, VID 0x2341 PID 0x8036).
> + Exposes the battery status and capacity via the power_supply interface.
[ ... ]
> diff --git a/drivers/hid/hid-lattepanda-iota-ups.c b/drivers/hid/hid-lattepanda-iota-ups.c
> new file mode 100644
> index 0000000000000..f5d522695081e
> --- /dev/null
> +++ b/drivers/hid/hid-lattepanda-iota-ups.c
> @@ -0,0 +1,409 @@
[ ... ]
> +static const struct hid_device_id iota_ups_devices[] = {
> + { HID_USB_DEVICE(USB_VENDOR_ID_LATTEPANDA_IOTA,
> + USB_DEVICE_ID_LATTEPANDA_IOTA_UPS) },
> + { }
> +};
> +MODULE_DEVICE_TABLE(hid, iota_ups_devices);
[Severity: High]
Does this driver unconditionally bind to the generic Arduino Leonardo VID/PID
(0x2341/0x8036)?
Since it matches the standard development board ID and uses HID_CONNECT_HIDRAW
without HID_CONNECT_HIDINPUT, will this prevent any Arduino Leonardo acting as
a standard keyboard, mouse, or gamepad from functioning properly?
The driver might need to inspect the HID report descriptor during probe()
(e.g., checking for specific report IDs or usages) to confirm it is actually
communicating with the custom UPS firmware before returning success.
[ ... ]
> +static int iota_ups_raw_event(struct hid_device *hdev,
> + struct hid_report *report,
> + u8 *data, int size)
> +{
[ ... ]
> + /*
> + * Notify the power_supply core outside the spinlock to avoid
> + * a deadlock; power_supply_changed() may call back into
> + * get_property() which acquires the same lock.
> + */
> + if (changed && ups->psu)
> + power_supply_changed(ups->psu);
[Severity: Low]
Could there be a data race when accessing ups->psu here?
In iota_ups_register_work(), ups->psu is assigned without synchronization.
Concurrently, iota_ups_raw_event() reads ups->psu outside of the spinlock.
While x86 aligned pointer writes are atomic (preventing partial pointer reads),
this is undefined behavior in C. Using WRITE_ONCE() and READ_ONCE(), or safely
reading the pointer inside the existing ups->lock critical section, would
prevent this.
> +
> + return 0;
> +}
[ ... ]
> +static void iota_ups_remove(struct hid_device *hdev)
> +{
> + struct iota_ups *ups = hid_get_drvdata(hdev);
> +
> + cancel_work_sync(&ups->register_work);
[Severity: Medium]
Will device removal block the USB disconnect process for up to 3 seconds if
the device is unplugged during initialization?
If the device is abruptly disconnected while iota_ups_register_work() is still
waiting in wait_for_completion_timeout(), cancel_work_sync() will block here.
Since the physically removed device cannot send reports to trigger complete(),
the wait will always take the full 3 seconds. The driver likely needs to signal
completion proactively during removal to abort the wait before calling
cancel_work_sync().
> + hid_hw_close(hdev);
> + hid_hw_stop(hdev);
> +}
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260521031750.498110-1-andrewmaney05@gmail.com?part=1
^ permalink raw reply
* [PATCH v3] HID: Expose LattePanda IOTA UPS as a power_supply device
From: Andrew Maney @ 2026-05-21 3:17 UTC (permalink / raw)
To: jikos; +Cc: bentiss, linux-kernel, linux-input, Andrew Maney
This driver exposes the DFRobot LattePanda IOTA UPS board as a standard
power_supply device, allowing desktop environments and power management
tools such as UPower and systemd-logind to display battery status,
remaining capacity, and charging status without any special
configuration. It also enables automatic suspend or shutdown on low
battery and power profile configuration via any tool that supports the
standard power_supply interface.
The UPS presents itself as an Arduino Leonardo HID device running custom
firmware (VID 0x2341, PID 0x8036). It reports status and capacity via
HID reports 0x07 and 0x0C respectively.
The charge limit (80% or 100%) is configured via a physical DIP switch
on the UPS board and cannot be detected automatically. Userspace can
inform the driver of the configured limit via
charge_control_end_threshold.
---
Changes in v3:
- Deferred power_supply registration to workqueue to avoid blocking probe
- Fixed kernel panic when instantiated via uhid by checking hid_is_usb()
before dereferencing USB-specific structures
- Fixed ERR_PTR dereference in raw_event by only assigning ups->psu on
successful registration
- Fixed data race on ups->charge_limit using spin_lock_irqsave()
- Removed TIME_TO_EMPTY_NOW and TIME_TO_FULL_NOW properties to avoid
spurious shutdowns
- Changed plugged-in but not charging state from FULL to NOT_CHARGING
- Used devm_kasprintf() for a unique sysfs name in order to support
multiple devices
- Added POWER_SUPPLY and HIDRAW dependencies to Kconfig
- Used %pe for more human-readable error messages
Changes in v2:
- Rebased on top of the current tree
- Moved vendor and device IDs to drivers/hid/hid-ids.h
- Added Kconfig entry under HID bus support -> Special HID drivers
- Added build rule to drivers/hid/Makefile
Signed-off-by: Andrew Maney <andrewmaney05@gmail.com>
---
MAINTAINERS | 6 +
drivers/hid/Kconfig | 10 +
drivers/hid/Makefile | 1 +
drivers/hid/hid-ids.h | 3 +
drivers/hid/hid-lattepanda-iota-ups.c | 409 ++++++++++++++++++++++++++
5 files changed, 429 insertions(+)
create mode 100644 drivers/hid/hid-lattepanda-iota-ups.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 10e825318..d80721c2c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11416,6 +11416,12 @@ F: include/uapi/linux/hid*
F: samples/hid/
F: tools/testing/selftests/hid/
+HID LATTEPANDA IOTA UPS DRIVER
+M: Andrew Maney <andrewmaney05@gmail.com>
+L: linux-input@vger.kernel.org
+S: Maintained
+F: drivers/hid/hid-lattepanda-iota-ups.c
+
HID LOGITECH DRIVERS
R: Filipe Laíns <lains@riseup.net>
L: linux-input@vger.kernel.org
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index ff2f580b6..21ffc2fd0 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -510,6 +510,16 @@ config HID_KYSONA
Say Y here if you have a Kysona M600 mouse
and want to be able to read its battery capacity.
+config HID_LATTEPANDA_IOTA_UPS
+ tristate "LattePanda IOTA UPS"
+ depends on USB_HID && USB_HIDDEV && X86 && POWER_SUPPLY
+ help
+ Support for the LattePanda IOTA UPS (DFRobot, VID 0x2341 PID 0x8036).
+ Exposes the battery status and capacity via the power_supply interface.
+
+ To compile as a module, choose M here: the module will be
+ called hid-lattepanda-iota-ups.
+
config HID_UCLOGIC
tristate "UC-Logic"
depends on USB_HID
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index 0597fd6a4..d7ad3fc8f 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -74,6 +74,7 @@ obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o
obj-$(CONFIG_HID_KEYTOUCH) += hid-keytouch.o
obj-$(CONFIG_HID_KYE) += hid-kye.o
obj-$(CONFIG_HID_KYSONA) += hid-kysona.o
+obj-$(CONFIG_HID_LATTEPANDA_IOTA_UPS) += hid-lattepanda-iota-ups.o
obj-$(CONFIG_HID_LCPOWER) += hid-lcpower.o
obj-$(CONFIG_HID_LENOVO) += hid-lenovo.o
obj-$(CONFIG_HID_LENOVO_GO) += hid-lenovo-go.o
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 4657d96fb..6ded2c943 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -859,6 +859,9 @@
#define USB_DEVICE_ID_LD_HYBRID 0x2090
#define USB_DEVICE_ID_LD_HEATCONTROL 0x20A0
+#define USB_VENDOR_ID_LATTEPANDA_IOTA 0x2341
+#define USB_DEVICE_ID_LATTEPANDA_IOTA_UPS 0x8036
+
#define USB_VENDOR_ID_LENOVO 0x17ef
#define USB_DEVICE_ID_LENOVO_TPKBD 0x6009
#define USB_DEVICE_ID_LENOVO_CUSBKBD 0x6047
diff --git a/drivers/hid/hid-lattepanda-iota-ups.c b/drivers/hid/hid-lattepanda-iota-ups.c
new file mode 100644
index 000000000..f5d522695
--- /dev/null
+++ b/drivers/hid/hid-lattepanda-iota-ups.c
@@ -0,0 +1,409 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/power_supply.h>
+#include <linux/completion.h>
+#include <linux/workqueue.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/hid.h>
+#include <linux/usb.h>
+#include "hid-ids.h"
+
+#define REPORT_ID_CAPACITY 0x0C
+#define REPORT_ID_STATUS 0x07
+
+#define STATUS_DISCHARGING BIT(1)
+#define STATUS_PLUGGED_IN BIT(0)
+#define STATUS_CHARGING BIT(2)
+
+MODULE_AUTHOR("Andrew Maney");
+MODULE_DESCRIPTION("LattePanda IOTA UPS power supply driver");
+MODULE_LICENSE("GPL");
+
+struct iota_ups {
+ struct power_supply_desc psu_desc;
+ struct power_supply *psu;
+ struct hid_device *hiddev;
+ spinlock_t lock; /* Protects cached HID report values */
+
+ /* Cached values that are updated from HID reports */
+ bool plugged_in;
+ char serial[64];
+ int charge_limit;
+ int psu_status;
+ int capacity;
+
+ /*
+ * Wait for both status and capacity reports before registering
+ * with the power_supply core, so initial values are correct and
+ * not erroneous.
+ */
+ struct completion got_initial_data;
+ struct work_struct register_work;
+ bool got_capacity;
+ bool data_ready;
+ bool got_status;
+};
+
+static enum power_supply_property iota_ups_properties[] = {
+ POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD,
+ POWER_SUPPLY_PROP_SERIAL_NUMBER,
+ POWER_SUPPLY_PROP_MANUFACTURER,
+ POWER_SUPPLY_PROP_MODEL_NAME,
+ POWER_SUPPLY_PROP_TECHNOLOGY,
+ POWER_SUPPLY_PROP_CAPACITY,
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_ONLINE,
+ POWER_SUPPLY_PROP_STATUS,
+ POWER_SUPPLY_PROP_SCOPE,
+};
+
+static const struct hid_device_id iota_ups_devices[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_LATTEPANDA_IOTA,
+ USB_DEVICE_ID_LATTEPANDA_IOTA_UPS) },
+ { }
+};
+MODULE_DEVICE_TABLE(hid, iota_ups_devices);
+
+static int iota_ups_get_property(struct power_supply *supply,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct iota_ups *ups = power_supply_get_drvdata(supply);
+ unsigned long flags;
+
+ spin_lock_irqsave(&ups->lock, flags);
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_STATUS:
+ val->intval = ups->psu_status;
+ break;
+
+ /* Remaining capacity as a percentage from 0 to 100 */
+ case POWER_SUPPLY_PROP_CAPACITY:
+ val->intval = ups->capacity;
+ break;
+
+ /* The UPS is always present if the driver is loaded */
+ case POWER_SUPPLY_PROP_PRESENT:
+ val->intval = 1;
+ break;
+
+ /* Whether mains power is connected */
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval = ups->plugged_in ? 1 : 0;
+ break;
+
+ /*
+ * The UPS board supplies power to the IOTA and any
+ * peripherals connected to it, therefore its scope
+ * is system-wide.
+ */
+ case POWER_SUPPLY_PROP_SCOPE:
+ val->intval = POWER_SUPPLY_SCOPE_SYSTEM;
+ break;
+
+ /* V1.0 only accepts 18650 Li-ion cells */
+ case POWER_SUPPLY_PROP_TECHNOLOGY:
+ val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
+ break;
+
+ /* 80% or 100%, configured via a DIP switch on the UPS board */
+ case POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD:
+ val->intval = ups->charge_limit;
+ break;
+
+ case POWER_SUPPLY_PROP_MANUFACTURER:
+ val->strval = "DFRobot";
+ break;
+
+ case POWER_SUPPLY_PROP_MODEL_NAME:
+ val->strval = "LattePanda IOTA UPS";
+ break;
+
+ /* Retrieved from the USB descriptor */
+ case POWER_SUPPLY_PROP_SERIAL_NUMBER:
+ val->strval = ups->serial;
+ break;
+
+ default:
+ spin_unlock_irqrestore(&ups->lock, flags);
+ return -EINVAL;
+ }
+
+ spin_unlock_irqrestore(&ups->lock, flags);
+ return 0;
+}
+
+static int iota_ups_set_property(struct power_supply *supply,
+ enum power_supply_property psp,
+ const union power_supply_propval *val)
+{
+ struct iota_ups *ups = power_supply_get_drvdata(supply);
+
+ if (psp == POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD) {
+ unsigned long flags;
+
+ /*
+ * V1.0 supports 80% and 100% charge limits only, which is
+ * set via a DIP switch on the board. This property allows
+ * userspace to inform the driver which limit is configured.
+ */
+ if (val->intval != 80 && val->intval != 100)
+ return -EINVAL;
+
+ spin_lock_irqsave(&ups->lock, flags);
+ ups->charge_limit = val->intval;
+ spin_unlock_irqrestore(&ups->lock, flags);
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int iota_ups_property_is_writable(struct power_supply *supply,
+ enum power_supply_property psp)
+{
+ return psp == POWER_SUPPLY_PROP_CHARGE_CONTROL_END_THRESHOLD;
+}
+
+static int iota_ups_raw_event(struct hid_device *hdev,
+ struct hid_report *report,
+ u8 *data, int size)
+{
+ struct iota_ups *ups = hid_get_drvdata(hdev);
+ unsigned long flags;
+ bool changed = false;
+
+ /* All of the UPS's reports are at least 2 bytes */
+ if (size < 2)
+ return 0;
+
+ spin_lock_irqsave(&ups->lock, flags);
+
+ switch (data[0]) {
+ case REPORT_ID_STATUS: {
+ u8 status = data[1];
+ int new_status;
+ bool plugged_in = !!(status & STATUS_PLUGGED_IN);
+
+ /*
+ * The UPS status is determined as follows:
+ * Battery full:
+ * UPS is plugged in
+ * Battery is at full capacity
+ *
+ * Battery charging:
+ * UPS is plugged in
+ * Battery is not at full capacity
+ *
+ * Battery discharging:
+ * UPS is not plugged in
+ *
+ * Battery not charging:
+ * UPS is plugged in
+ * UPS has halted charging for some reason
+ *
+ * Unknown:
+ * None of the above conditions are met
+ */
+ if (status & STATUS_CHARGING) {
+ if (ups->capacity >= ups->charge_limit)
+ new_status = POWER_SUPPLY_STATUS_FULL;
+ else
+ new_status = POWER_SUPPLY_STATUS_CHARGING;
+
+ } else if (status & STATUS_DISCHARGING) {
+ new_status = POWER_SUPPLY_STATUS_DISCHARGING;
+
+ } else if (plugged_in) {
+ new_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+
+ } else {
+ new_status = POWER_SUPPLY_STATUS_UNKNOWN;
+ }
+
+ if (new_status != ups->psu_status ||
+ plugged_in != ups->plugged_in) {
+ ups->plugged_in = plugged_in;
+ ups->psu_status = new_status;
+ changed = true;
+ }
+
+ ups->got_status = true;
+ break;
+ }
+
+ case REPORT_ID_CAPACITY: {
+ int new_cap = clamp((int)data[1], 0, 100);
+
+ if (new_cap != ups->capacity) {
+ ups->capacity = new_cap;
+ changed = true;
+ }
+
+ ups->got_capacity = true;
+ break;
+ }
+ }
+
+ /*
+ * Signal that the UPS is ready to be registered because we have
+ * received both capacity and status reports.
+ */
+ if (!ups->data_ready && ups->got_status && ups->got_capacity) {
+ ups->data_ready = true;
+ complete(&ups->got_initial_data);
+ }
+
+ spin_unlock_irqrestore(&ups->lock, flags);
+
+ /*
+ * Notify the power_supply core outside the spinlock to avoid
+ * a deadlock; power_supply_changed() may call back into
+ * get_property() which acquires the same lock.
+ */
+ if (changed && ups->psu)
+ power_supply_changed(ups->psu);
+
+ return 0;
+}
+
+static void iota_ups_register_work(struct work_struct *work)
+{
+ struct iota_ups *ups = container_of(work, struct iota_ups, register_work);
+ struct power_supply_config psu_config = {};
+ struct power_supply *psu;
+
+ /*
+ * Wait for both status and capacity reports before registering.
+ * The device sends reports every ~1 second, so 3 seconds is safe.
+ * We wait here in order to prevent registration in an unknown
+ * state, since this could cause emergency shutdowns or other
+ * undesired effects.
+ */
+ wait_for_completion_timeout(&ups->got_initial_data,
+ msecs_to_jiffies(3000));
+
+ /* Configure the UPS's power supply properties */
+ ups->psu_desc.name = devm_kasprintf(&ups->hiddev->dev, GFP_KERNEL,
+ "lattepanda-iota-ups.%s",
+ dev_name(&ups->hiddev->dev));
+
+ if (!ups->psu_desc.name) {
+ hid_err(ups->hiddev, "failed to allocate power supply name\n");
+ return;
+ }
+
+ ups->psu_desc.property_is_writeable = iota_ups_property_is_writable;
+ ups->psu_desc.num_properties = ARRAY_SIZE(iota_ups_properties);
+ ups->psu_desc.get_property = iota_ups_get_property;
+ ups->psu_desc.set_property = iota_ups_set_property;
+ ups->psu_desc.properties = iota_ups_properties;
+ ups->psu_desc.type = POWER_SUPPLY_TYPE_BATTERY;
+ psu_config.drv_data = ups;
+
+ /* Register the UPS as a power_supply device */
+ psu = devm_power_supply_register(&ups->hiddev->dev, &ups->psu_desc, &psu_config);
+ if (IS_ERR(psu)) {
+ hid_err(ups->hiddev, "power supply registration failed: %pe\n", psu);
+ return;
+ }
+
+ /*
+ * Finally, notify the power_supply core so userspace reads the correct
+ * initial state immediately after registration.
+ */
+ ups->psu = psu;
+ power_supply_changed(ups->psu);
+ hid_info(ups->hiddev, "LattePanda IOTA UPS registered as a power_supply device\n");
+}
+
+static int iota_ups_probe(struct hid_device *hdev,
+ const struct hid_device_id *id)
+{
+ struct iota_ups *ups;
+ int ret;
+
+ ups = devm_kzalloc(&hdev->dev, sizeof(*ups), GFP_KERNEL);
+ if (!ups)
+ return -ENOMEM;
+
+ ups->hiddev = hdev;
+ ups->psu_status = POWER_SUPPLY_STATUS_UNKNOWN;
+
+ /* 50% is a safe default if wait_for_completion_timeout() times out. */
+ ups->capacity = 50;
+
+ /*
+ * Default to 100% to prevent unexpected shutdowns.
+ * Userspace can update this via charge_control_end_threshold.
+ */
+ ups->charge_limit = 100;
+
+ init_completion(&ups->got_initial_data);
+ spin_lock_init(&ups->lock);
+ hid_set_drvdata(hdev, ups);
+
+ /*
+ * Retrieve the UPS's serial number from the USB descriptor. If the device is not
+ * a USB device, we can use the unique device identifier as the serial number.
+ */
+ if (hid_is_usb(hdev)) {
+ struct usb_device *udev = to_usb_device(hdev->dev.parent->parent);
+
+ if (udev->serial)
+ strscpy(ups->serial, udev->serial, sizeof(ups->serial));
+ else
+ strscpy(ups->serial, "Unknown", sizeof(ups->serial));
+ } else {
+ if (*hdev->uniq)
+ strscpy(ups->serial, hdev->uniq, sizeof(ups->serial));
+ else
+ strscpy(ups->serial, "Unknown", sizeof(ups->serial));
+ }
+
+ ret = hid_parse(hdev);
+ if (ret) {
+ hid_err(hdev, "HID parse failed: %pe\n", ERR_PTR(ret));
+ return ret;
+ }
+
+ ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW);
+ if (ret) {
+ hid_err(hdev, "HID hw start failed: %pe\n", ERR_PTR(ret));
+ return ret;
+ }
+
+ ret = hid_hw_open(hdev);
+ if (ret) {
+ hid_err(hdev, "HID hw open failed: %pe\n", ERR_PTR(ret));
+ goto err_stop;
+ }
+
+ /* Probe for the UPS in a worker queue so we don't halt the enumeration thread */
+ INIT_WORK(&ups->register_work, iota_ups_register_work);
+ schedule_work(&ups->register_work);
+ return 0;
+
+err_stop:
+ hid_hw_stop(hdev);
+ return ret;
+}
+
+static void iota_ups_remove(struct hid_device *hdev)
+{
+ struct iota_ups *ups = hid_get_drvdata(hdev);
+
+ cancel_work_sync(&ups->register_work);
+ hid_hw_close(hdev);
+ hid_hw_stop(hdev);
+}
+
+static struct hid_driver iota_ups_driver = {
+ .name = "lattepanda-iota-ups",
+ .id_table = iota_ups_devices,
+ .probe = iota_ups_probe,
+ .remove = iota_ups_remove,
+ .raw_event = iota_ups_raw_event,
+};
+module_hid_driver(iota_ups_driver);
--
2.54.0
^ permalink raw reply related
* Re: [syzbot] [input?] possible deadlock in tasklet_action_common (2)
From: Hillf Danton @ 2026-05-21 1:52 UTC (permalink / raw)
To: syzbot
Cc: dmitry.torokhov, linux-input, Sebastian Andrzej Siewior,
Tetsuo Handa, linux-kernel, syzkaller-bugs
In-Reply-To: <6a0de9e2.050a0220.18b3cb.000d.GAE@google.com>
> Date: Wed, 20 May 2026 10:05:38 -0700 [thread overview]
> Hello,
>
> syzbot found the following issue on:
>
> HEAD commit: e98d21c170b0 Add linux-next specific files for 20260508
> git tree: linux-next
> console output: https://syzkaller.appspot.com/x/log.txt?x=1354bfce580000
> kernel config: https://syzkaller.appspot.com/x/.config?x=59b98218d9b2edf4
> dashboard link: https://syzkaller.appspot.com/bug?extid=b5d7ab56d43de3fd5aac
> compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
>
> Unfortunately, I don't have any reproducer for this issue yet.
>
> Downloadable assets:
> disk image: https://storage.googleapis.com/syzbot-assets/66f2a00ee290/disk-e98d21c1.raw.xz
> vmlinux: https://storage.googleapis.com/syzbot-assets/6b982257ce9e/vmlinux-e98d21c1.xz
> kernel image: https://storage.googleapis.com/syzbot-assets/a73fbea43e1a/bzImage-e98d21c1.xz
>
> IMPORTANT: if you fix the issue, please add the following tag to the commit:
> Reported-by: syzbot+b5d7ab56d43de3fd5aac@syzkaller.appspotmail.com
>
> ======================================================
> WARNING: possible circular locking dependency detected
> syzkaller #0 Tainted: G L
> ------------------------------------------------------
> syz.2.4328/32663 is trying to acquire lock:
> ffff8880b8724168 (tasklet_sync_callback.cb_lock){+...}-{3:3}, at: spin_lock include/linux/spinlock_rt.h:45 [inline]
> ffff8880b8724168 (tasklet_sync_callback.cb_lock){+...}-{3:3}, at: tasklet_lock_callback kernel/softirq.c:881 [inline]
> ffff8880b8724168 (tasklet_sync_callback.cb_lock){+...}-{3:3}, at: tasklet_action_common+0xc5/0x610 kernel/softirq.c:931
>
> but task is already holding lock:
> ffff888058598270 (&dev->event_lock#2){+.+.}-{3:3}, at: spin_lock include/linux/spinlock_rt.h:45 [inline]
> ffff888058598270 (&dev->event_lock#2){+.+.}-{3:3}, at: class_spinlock_irqsave_constructor include/linux/spinlock.h:619 [inline]
> ffff888058598270 (&dev->event_lock#2){+.+.}-{3:3}, at: input_inject_event+0xa4/0x320 drivers/input/input.c:419
>
> which lock already depends on the new lock.
>
>
> the existing dependency chain (in reverse order) is:
>
> -> #1 (&dev->event_lock#2){+.+.}-{3:3}:
> rt_spin_lock+0x83/0x400 kernel/locking/spinlock_rt.c:56
> spin_lock include/linux/spinlock_rt.h:45 [inline]
> class_spinlock_irqsave_constructor include/linux/spinlock.h:619 [inline]
> input_inject_event+0xa4/0x320 drivers/input/input.c:419
> led_trigger_event+0x13b/0x220 drivers/leds/led-triggers.c:420
> kbd_propagate_led_state drivers/tty/vt/keyboard.c:1118 [inline]
> kbd_bh+0x1b4/0x2c0 drivers/tty/vt/keyboard.c:1297
> tasklet_action_common+0x31c/0x610 kernel/softirq.c:942
> handle_softirqs+0x1de/0x6d0 kernel/softirq.c:626
> __do_softirq kernel/softirq.c:660 [inline]
> run_ktimerd+0x69/0x100 kernel/softirq.c:1155
> smpboot_thread_fn+0x541/0xa50 kernel/smpboot.c:160
> kthread+0x388/0x470 kernel/kthread.c:436
> ret_from_fork+0x514/0xb70 arch/x86/kernel/process.c:158
> ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
>
Deadlock if the timer thread is preempted
timer thread
tasklet_sync_callback.cb_lock
// preempted
&dev->event_lock
do softirq
acquire tasklet_sync_callback.cb_lock
acquire &dev->event_lock
> -> #0 (tasklet_sync_callback.cb_lock){+...}-{3:3}:
> check_prev_add kernel/locking/lockdep.c:3167 [inline]
> check_prevs_add kernel/locking/lockdep.c:3286 [inline]
> validate_chain kernel/locking/lockdep.c:3910 [inline]
> __lock_acquire+0x15a5/0x2d10 kernel/locking/lockdep.c:5239
> lock_acquire+0x106/0x350 kernel/locking/lockdep.c:5870
> rt_spin_lock+0x83/0x400 kernel/locking/spinlock_rt.c:56
> spin_lock include/linux/spinlock_rt.h:45 [inline]
> tasklet_lock_callback kernel/softirq.c:881 [inline]
> tasklet_action_common+0xc5/0x610 kernel/softirq.c:931
> handle_softirqs+0x1de/0x6d0 kernel/softirq.c:626
> __do_softirq kernel/softirq.c:660 [inline]
> __local_bh_enable_ip+0x170/0x2b0 kernel/softirq.c:302
> local_bh_enable include/linux/bottom_half.h:33 [inline]
> __alloc_skb+0x1aa/0x7d0 net/core/skbuff.c:697
> alloc_skb include/linux/skbuff.h:1381 [inline]
> hidp_send_message+0xb5/0x230 net/bluetooth/hidp/core.c:111
> hidp_send_intr_message net/bluetooth/hidp/core.c:143 [inline]
> hidp_input_event+0x2a4/0x380 net/bluetooth/hidp/core.c:175
> input_event_dispose+0x80/0x6b0 drivers/input/input.c:322
> input_inject_event+0x1d7/0x320 drivers/input/input.c:424
> kbd_led_trigger_activate+0xbc/0x100 drivers/tty/vt/keyboard.c:1074
> led_trigger_set+0x53b/0x960 drivers/leds/led-triggers.c:220
> led_match_default_trigger drivers/leds/led-triggers.c:277 [inline]
> led_trigger_set_default+0x266/0x2a0 drivers/leds/led-triggers.c:300
> led_classdev_register_ext+0x787/0x9c0 drivers/leds/led-class.c:581
> led_classdev_register include/linux/leds.h:274 [inline]
> input_leds_connect+0x517/0x790 drivers/input/input-leds.c:145
> input_attach_handler drivers/input/input.c:1011 [inline]
> input_register_device+0xce0/0x1140 drivers/input/input.c:2395
> hidp_session_dev_add net/bluetooth/hidp/core.c:861 [inline]
> hidp_session_probe+0x1a5/0x8a0 net/bluetooth/hidp/core.c:1139
> l2cap_register_user+0xc2/0x1d0 net/bluetooth/l2cap_core.c:1725
> hidp_connection_add+0x158b/0x1a20 net/bluetooth/hidp/core.c:1411
> do_hidp_sock_ioctl net/bluetooth/hidp/sock.c:81 [inline]
> hidp_sock_ioctl+0x403/0x650 net/bluetooth/hidp/sock.c:128
> sock_do_ioctl+0x101/0x320 net/socket.c:1328
> sock_ioctl+0x5c9/0x7f0 net/socket.c:1449
> vfs_ioctl fs/ioctl.c:51 [inline]
> __do_sys_ioctl fs/ioctl.c:597 [inline]
> __se_sys_ioctl+0xff/0x170 fs/ioctl.c:583
> do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
> do_syscall_64+0x15f/0xf80 arch/x86/entry/syscall_64.c:94
> entry_SYSCALL_64_after_hwframe+0x77/0x7f
>
> other info that might help us debug this:
>
> Possible unsafe locking scenario:
>
> CPU0 CPU1
> ---- ----
> lock(&dev->event_lock#2);
> lock(tasklet_sync_callback.cb_lock);
> lock(&dev->event_lock#2);
> lock(tasklet_sync_callback.cb_lock);
>
> *** DEADLOCK ***
>
> 10 locks held by syz.2.4328/32663:
> #0: ffff88805ebb3370 (&conn->lock#2){+.+.}-{4:4}, at: l2cap_register_user+0x35/0x1d0 net/bluetooth/l2cap_core.c:1712
> #1: ffffffff8f73d960 (hidp_session_sem){++++}-{4:4}, at: hidp_session_probe+0x98/0x8a0 net/bluetooth/hidp/core.c:1129
> #2: ffffffff8f006e58 (input_mutex){+.+.}-{4:4}, at: class_mutex_intr_constructor include/linux/mutex.h:255 [inline]
> #2: ffffffff8f006e58 (input_mutex){+.+.}-{4:4}, at: input_register_device+0xa56/0x1140 drivers/input/input.c:2391
> #3: ffff8880125ea860 (&led_cdev->led_access){+.+.}-{4:4}, at: led_classdev_register_ext+0x484/0x9c0 drivers/leds/led-class.c:539
> #4: ffffffff8e9c4400 (triggers_list_lock){++++}-{4:4}, at: led_trigger_set_default+0x77/0x2a0 drivers/leds/led-triggers.c:297
> #5: ffff8880125ea788 (&led_cdev->trigger_lock){+.+.}-{4:4}, at: led_trigger_set_default+0x87/0x2a0 drivers/leds/led-triggers.c:298
> #6: ffff888058598270 (&dev->event_lock#2){+.+.}-{3:3}, at: spin_lock include/linux/spinlock_rt.h:45 [inline]
> #6: ffff888058598270 (&dev->event_lock#2){+.+.}-{3:3}, at: class_spinlock_irqsave_constructor include/linux/spinlock.h:619 [inline]
> #6: ffff888058598270 (&dev->event_lock#2){+.+.}-{3:3}, at: input_inject_event+0xa4/0x320 drivers/input/input.c:419
> #7: ffffffff8e1c8240 (rcu_read_lock){....}-{1:3}, at: rcu_lock_acquire include/linux/rcupdate.h:300 [inline]
> #7: ffffffff8e1c8240 (rcu_read_lock){....}-{1:3}, at: rcu_read_lock include/linux/rcupdate.h:838 [inline]
> #7: ffffffff8e1c8240 (rcu_read_lock){....}-{1:3}, at: __rt_spin_lock kernel/locking/spinlock_rt.c:50 [inline]
> #7: ffffffff8e1c8240 (rcu_read_lock){....}-{1:3}, at: rt_spin_lock+0x1e0/0x400 kernel/locking/spinlock_rt.c:57
> #8: ffffffff8e1c8240 (rcu_read_lock){....}-{1:3}, at: rcu_lock_acquire include/linux/rcupdate.h:300 [inline]
> #8: ffffffff8e1c8240 (rcu_read_lock){....}-{1:3}, at: rcu_read_lock include/linux/rcupdate.h:838 [inline]
> #8: ffffffff8e1c8240 (rcu_read_lock){....}-{1:3}, at: class_rcu_constructor include/linux/rcupdate.h:1181 [inline]
> #8: ffffffff8e1c8240 (rcu_read_lock){....}-{1:3}, at: input_inject_event+0xb0/0x320 drivers/input/input.c:420
> #9: ffffffff8e1c8240 (rcu_read_lock){....}-{1:3}, at: __local_bh_disable_ip+0x3c/0x420 kernel/softirq.c:163
>
> stack backtrace:
> CPU: 1 UID: 0 PID: 32663 Comm: syz.2.4328 Tainted: G L syzkaller #0 PREEMPT_{RT,(full)}
> Tainted: [L]=SOFTLOCKUP
> Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 04/18/2026
> Call Trace:
> <TASK>
> dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120
> print_circular_bug+0x2e1/0x300 kernel/locking/lockdep.c:2045
> check_noncircular+0x12e/0x150 kernel/locking/lockdep.c:2177
> check_prev_add kernel/locking/lockdep.c:3167 [inline]
> check_prevs_add kernel/locking/lockdep.c:3286 [inline]
> validate_chain kernel/locking/lockdep.c:3910 [inline]
> __lock_acquire+0x15a5/0x2d10 kernel/locking/lockdep.c:5239
> lock_acquire+0x106/0x350 kernel/locking/lockdep.c:5870
> rt_spin_lock+0x83/0x400 kernel/locking/spinlock_rt.c:56
> spin_lock include/linux/spinlock_rt.h:45 [inline]
> tasklet_lock_callback kernel/softirq.c:881 [inline]
> tasklet_action_common+0xc5/0x610 kernel/softirq.c:931
> handle_softirqs+0x1de/0x6d0 kernel/softirq.c:626
> __do_softirq kernel/softirq.c:660 [inline]
> __local_bh_enable_ip+0x170/0x2b0 kernel/softirq.c:302
> local_bh_enable include/linux/bottom_half.h:33 [inline]
> __alloc_skb+0x1aa/0x7d0 net/core/skbuff.c:697
> alloc_skb include/linux/skbuff.h:1381 [inline]
> hidp_send_message+0xb5/0x230 net/bluetooth/hidp/core.c:111
> hidp_send_intr_message net/bluetooth/hidp/core.c:143 [inline]
> hidp_input_event+0x2a4/0x380 net/bluetooth/hidp/core.c:175
> input_event_dispose+0x80/0x6b0 drivers/input/input.c:322
> input_inject_event+0x1d7/0x320 drivers/input/input.c:424
> kbd_led_trigger_activate+0xbc/0x100 drivers/tty/vt/keyboard.c:1074
> led_trigger_set+0x53b/0x960 drivers/leds/led-triggers.c:220
> led_match_default_trigger drivers/leds/led-triggers.c:277 [inline]
> led_trigger_set_default+0x266/0x2a0 drivers/leds/led-triggers.c:300
> led_classdev_register_ext+0x787/0x9c0 drivers/leds/led-class.c:581
> led_classdev_register include/linux/leds.h:274 [inline]
> input_leds_connect+0x517/0x790 drivers/input/input-leds.c:145
> input_attach_handler drivers/input/input.c:1011 [inline]
> input_register_device+0xce0/0x1140 drivers/input/input.c:2395
> hidp_session_dev_add net/bluetooth/hidp/core.c:861 [inline]
> hidp_session_probe+0x1a5/0x8a0 net/bluetooth/hidp/core.c:1139
> l2cap_register_user+0xc2/0x1d0 net/bluetooth/l2cap_core.c:1725
> hidp_connection_add+0x158b/0x1a20 net/bluetooth/hidp/core.c:1411
> do_hidp_sock_ioctl net/bluetooth/hidp/sock.c:81 [inline]
> hidp_sock_ioctl+0x403/0x650 net/bluetooth/hidp/sock.c:128
> sock_do_ioctl+0x101/0x320 net/socket.c:1328
> sock_ioctl+0x5c9/0x7f0 net/socket.c:1449
> vfs_ioctl fs/ioctl.c:51 [inline]
> __do_sys_ioctl fs/ioctl.c:597 [inline]
> __se_sys_ioctl+0xff/0x170 fs/ioctl.c:583
> do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
> do_syscall_64+0x15f/0xf80 arch/x86/entry/syscall_64.c:94
> entry_SYSCALL_64_after_hwframe+0x77/0x7f
> RIP: 0033:0x7fcb5e6cce59
> Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
> RSP: 002b:00007fcb5c905028 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
> RAX: ffffffffffffffda RBX: 00007fcb5e946090 RCX: 00007fcb5e6cce59
> RDX: 00002000000000c0 RSI: 00000000400448c8 RDI: 0000000000000009
> RBP: 00007fcb5e762d6f R08: 0000000000000000 R09: 0000000000000000
> R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
> R13: 00007fcb5e946128 R14: 00007fcb5e946090 R15: 00007ffddb8adae8
> </TASK>
^ permalink raw reply
* Re: [PATCH 09/10] [v6 omap] ARM: dts: omap2: add stlc4560 spi-wireless node
From: Andreas Kemnade @ 2026-05-20 21:46 UTC (permalink / raw)
To: Arnd Bergmann
Cc: linux-gpio, linux-kernel, Arnd Bergmann, Christian Lamparter,
Johannes Berg, Aaro Koskinen, Kevin Hilman, Roger Quadros,
Tony Lindgren, Thomas Bogendoerfer, John Paul Adrian Glaubitz,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
H. Peter Anvin, Linus Walleij, Bartosz Golaszewski,
Dmitry Torokhov, Lee Jones, Pavel Machek, Matti Vaittinen,
Florian Fainelli, Jonas Gorski, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
linux-wireless, linux-omap, linux-arm-kernel, linux-mips,
linux-sh, linux-input, linux-leds, netdev, Krzysztof Kozlowski
In-Reply-To: <20260520183815.2510387-10-arnd@kernel.org>
On Wed, 20 May 2026 20:38:14 +0200
Arnd Bergmann <arnd@kernel.org> wrote:
> From: Arnd Bergmann <arnd@arndb.de>
>
> Converted from the platform_device creation in board-n8x0.c.
>
> Link: https://lore.kernel.org/all/20230314163201.955689-1-arnd@kernel.org/
> Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
> Reviewed-by: Linus Walleij <linusw@kernel.org>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
> v6: no changes
> v1 through v5: adaptations that correspond to the binding updates
> ---
> arch/arm/boot/dts/ti/omap/omap2.dtsi | 4 ++++
> arch/arm/boot/dts/ti/omap/omap2420-n8x0-common.dtsi | 12 ++++++++++++
> 2 files changed, 16 insertions(+)
>
Reviewed-by: Andreas Kemnade <andreas@kemnade.info>
^ permalink raw reply
* Re: [PATCH 09/10] [v6 omap] ARM: dts: omap2: add stlc4560 spi-wireless node
From: Johannes Berg @ 2026-05-20 21:39 UTC (permalink / raw)
To: Arnd Bergmann, linux-gpio
Cc: linux-kernel, Arnd Bergmann, Christian Lamparter, Aaro Koskinen,
Andreas Kemnade, Kevin Hilman, Roger Quadros, Tony Lindgren,
Thomas Bogendoerfer, John Paul Adrian Glaubitz, Thomas Gleixner,
Ingo Molnar, Borislav Petkov, Dave Hansen, x86, H. Peter Anvin,
Linus Walleij, Bartosz Golaszewski, Dmitry Torokhov, Lee Jones,
Pavel Machek, Matti Vaittinen, Florian Fainelli, Jonas Gorski,
Andrew Lunn, Vladimir Oltean, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, linux-wireless, linux-omap,
linux-arm-kernel, linux-mips, linux-sh, linux-input, linux-leds,
netdev, Krzysztof Kozlowski
In-Reply-To: <20260520183815.2510387-10-arnd@kernel.org>
On Wed, 2026-05-20 at 20:38 +0200, Arnd Bergmann wrote:
>
> v1 through v5: adaptations that correspond to the binding updates
FWIW, I had just applied v5 of these three patches today, but didn't
send out a pull request yet. I'll do that tomorrow morning.
johannes
^ permalink raw reply
* Re: [PATCH v6 2/6] dt-bindings: input: cpcap-pwrbutton: convert to DT schema
From: Rob Herring (Arm) @ 2026-05-20 20:13 UTC (permalink / raw)
To: Svyatoslav Ryhel
Cc: Pavel Machek, linux-leds, Dmitry Torokhov, Lee Jones,
Conor Dooley, linux-kernel, Krzysztof Kozlowski, linux-input,
devicetree
In-Reply-To: <20260520182124.117863-3-clamor95@gmail.com>
On Wed, 20 May 2026 21:21:20 +0300, Svyatoslav Ryhel wrote:
> Convert power button devicetree bindings for the Motorola CPCAP MFD from
> TXT to YAML format. This patch does not change any functionality; the
> bindings remain the same.
>
> Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
> Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
> ---
> .../bindings/input/cpcap-pwrbutton.txt | 20 ------------
> .../input/motorola,cpcap-pwrbutton.yaml | 32 +++++++++++++++++++
> 2 files changed, 32 insertions(+), 20 deletions(-)
> delete mode 100644 Documentation/devicetree/bindings/input/cpcap-pwrbutton.txt
> create mode 100644 Documentation/devicetree/bindings/input/motorola,cpcap-pwrbutton.yaml
>
My bot found errors running 'make dt_binding_check' on your patch:
yamllint warnings/errors:
dtschema/dtc warnings/errors:
doc reference errors (make refcheckdocs):
Warning: Documentation/devicetree/bindings/input/motorola,cpcap-pwrbutton.yaml references a file that doesn't exist: Documentation/devicetree/bindings/mfd/motorola,cpcap.yaml
Warning: Documentation/devicetree/bindings/mfd/motorola-cpcap.txt references a file that doesn't exist: Documentation/devicetree/bindings/input/cpcap-pwrbutton.txt
Documentation/devicetree/bindings/input/motorola,cpcap-pwrbutton.yaml: Documentation/devicetree/bindings/mfd/motorola,cpcap.yaml
Documentation/devicetree/bindings/mfd/motorola-cpcap.txt: Documentation/devicetree/bindings/input/cpcap-pwrbutton.txt
See https://patchwork.kernel.org/project/devicetree/patch/20260520182124.117863-3-clamor95@gmail.com
The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.
If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:
pip3 install dtschema --upgrade
Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.
^ permalink raw reply
* Re: [PATCH v6 1/6] dt-bindings: leds: leds-cpcap: convert to DT schema
From: Rob Herring (Arm) @ 2026-05-20 20:13 UTC (permalink / raw)
To: Svyatoslav Ryhel
Cc: linux-input, linux-leds, linux-kernel, devicetree, Conor Dooley,
Pavel Machek, Dmitry Torokhov, Krzysztof Kozlowski, Lee Jones
In-Reply-To: <20260520182124.117863-2-clamor95@gmail.com>
On Wed, 20 May 2026 21:21:19 +0300, Svyatoslav Ryhel wrote:
> Convert LEDs devicetree bindings for the Motorola CPCAP MFD from TXT to
> YAML format. This patch does not change any functionality; the bindings
> remain the same.
>
> Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
> Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
> ---
> .../devicetree/bindings/leds/leds-cpcap.txt | 29 -------------
> .../bindings/leds/motorola,cpcap-leds.yaml | 42 +++++++++++++++++++
> 2 files changed, 42 insertions(+), 29 deletions(-)
> delete mode 100644 Documentation/devicetree/bindings/leds/leds-cpcap.txt
> create mode 100644 Documentation/devicetree/bindings/leds/motorola,cpcap-leds.yaml
>
My bot found errors running 'make dt_binding_check' on your patch:
yamllint warnings/errors:
dtschema/dtc warnings/errors:
doc reference errors (make refcheckdocs):
Warning: Documentation/devicetree/bindings/leds/motorola,cpcap-leds.yaml references a file that doesn't exist: Documentation/devicetree/bindings/mfd/motorola,cpcap.yaml
Warning: Documentation/devicetree/bindings/mfd/motorola-cpcap.txt references a file that doesn't exist: Documentation/devicetree/bindings/leds/leds-cpcap.txt
Documentation/devicetree/bindings/leds/motorola,cpcap-leds.yaml: Documentation/devicetree/bindings/mfd/motorola,cpcap.yaml
Documentation/devicetree/bindings/mfd/motorola-cpcap.txt: Documentation/devicetree/bindings/leds/leds-cpcap.txt
See https://patchwork.kernel.org/project/devicetree/patch/20260520182124.117863-2-clamor95@gmail.com
The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.
If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:
pip3 install dtschema --upgrade
Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.
^ permalink raw reply
* Re: [PATCH v2 5/6] tools/build: selftests: Allow versioning LLVM lld
From: Arnaldo Carvalho de Melo @ 2026-05-20 19:50 UTC (permalink / raw)
To: James Clark
Cc: sashiko-reviews, dmitry.torokhov, linux-perf-users, bpf,
linux-input
In-Reply-To: <ef5688a7-3e1d-47be-aca7-cc6e564e059c@linaro.org>
On Mon, May 18, 2026 at 10:47:53AM +0100, James Clark wrote:
>
>
> On 18/05/2026 10:32 am, sashiko-bot@kernel.org wrote:
> > Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> > - [Medium] Empty USE_LD variable causes clang build failure in selftests when ld.lld is not in PATH.
> > --
> >
> > commit 371ca22c55bb0fa6502ac06f7b33d63418ad16ff
> > Author: James Clark <james.clark@linaro.org>
> >
> > tools/build: selftests: Allow versioning LLVM lld
> >
> > This commit adds an LLD variable to Makefile.include to allow versioning of
> > LLVM's linker, keeping it consistent with the rest of the LLVM toolchain. It
> > modifies the BPF selftests Makefile to resolve the full path of the linker
> > using the command -v shell utility.
> >
> > > diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
> > > index 6ef6872adbc3e..836e783f0170e 100644
> > > --- a/tools/testing/selftests/bpf/Makefile
> > > +++ b/tools/testing/selftests/bpf/Makefile
> >
> > [ ... ]
> >
> > > @@ -245,9 +245,9 @@ $(OUTPUT)/%:%.c
> > > # LLVM's ld.lld doesn't support all the architectures, so use it only on x86
> > > ifeq ($(SRCARCH),$(filter $(SRCARCH),x86 riscv))
> > > -LLD := lld
> > > +USE_LD := $(shell command -v $(LLD))
> >
> > Does this cause the build to fail if the toolchain directory is not in the
> > system PATH?
> >
> > If a user explicitly specifies the compiler using an absolute path like
> > CLANG=/path/to/clang, but does not add the toolchain directory to their PATH,
> > the command -v utility will return an empty string.
>
> If they don't use LLVM= and use CLANG= with an absolute path then they need
> to set all the tools with an absolute path. That's the problem that setting
> the path with a prefix for all tools with LLVM= solved.
>
> I suppose this could _technically_ be a regression, but so could adding any
> new build rule that added a new tool that wouldn't be set in someones
> existing build command. Being that strict would mean we can't ever add new
> tools so I don't think this is an issue. And I don't think there's a way to
> solve this and also respect the documented rules of LLVM=
Hey, this touches several tools and libs, did you get acks besides the
one from Ian?
- Arnaldo
^ permalink raw reply
* Re: [PATCH v6 5/6] mfd: motorola-cpcap: diverge configuration per-board
From: sashiko-bot @ 2026-05-20 19:28 UTC (permalink / raw)
To: Svyatoslav Ryhel; +Cc: conor+dt, devicetree, dmitry.torokhov, linux-input, robh
In-Reply-To: <20260520182124.117863-6-clamor95@gmail.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Critical] Modifying the OF match table breaks backward compatibility with existing Device Trees.
- [Low] Casting a pointer directly to an enum causes a `-Wpointer-to-int-cast` compiler warning on 64-bit architectures.
--
commit d4fffaca1e4a78c4406875cbdeef7c59b0fe0b1a
Author: Svyatoslav Ryhel <clamor95@gmail.com>
mfd: motorola-cpcap: diverge configuration per-board
This commit introduces board-specific subdevice configurations for the
Motorola CPCAP MFD. It defines common, default, and mapphone device lists
and uses SPI/OF match data to select the variant.
> diff --git a/drivers/mfd/motorola-cpcap.c b/drivers/mfd/motorola-cpcap.c
> index d8243b956f875..5b6ca6b81c232 100644
> --- a/drivers/mfd/motorola-cpcap.c
> +++ b/drivers/mfd/motorola-cpcap.c
[ ... ]
> @@ -241,62 +229,58 @@ static int cpcap_resume(struct device *dev)
[ ... ]
> static int cpcap_probe(struct spi_device *spi)
> {
> struct cpcap_ddata *cpcap;
> + const struct mfd_cell *cells;
> + unsigned int num_cells;
> int ret;
>
> cpcap = devm_kzalloc(&spi->dev, sizeof(*cpcap), GFP_KERNEL);
> if (!cpcap)
> return -ENOMEM;
>
> + cpcap->variant = (enum cpcap_variant)spi_get_device_match_data(spi);
[Severity: Low]
Does this direct cast from a pointer to an enum cause a compiler warning on
64-bit architectures?
spi_get_device_match_data() returns a const void *, which is 64-bit on
64-bit architectures, while enum cpcap_variant is typically a 32-bit integer.
Casting directly from a 64-bit pointer to a 32-bit enum can trigger a
-Wpointer-to-int-cast warning and cause build failures when compiled with
-Werror.
Should the pointer be cast to an intermediate integer type like
(uintptr_t) or (unsigned long) first?
[ ... ]
> @@ -331,10 +315,29 @@ static int cpcap_probe(struct spi_device *spi)
[ ... ]
> +static const struct of_device_id cpcap_of_match[] = {
> + { .compatible = "motorola,cpcap", .data = (void *)CPCAP_DEFAULT },
> + { .compatible = "motorola,mapphone-cpcap", .data = (void *)CPCAP_MAPPHONE },
> + { /* sentinel */ }
> +};
[Severity: Critical]
Does this modification to the OF match table break backward compatibility with
existing Device Trees?
The Device Tree is considered a stable ABI in the kernel. This change reassigns
the existing "motorola,cpcap" compatible string to map to CPCAP_DEFAULT instead
of preserving its legacy behavior (which included Mapphone-specific child
nodes).
Older DTBs rely on "motorola,cpcap" to instantiate devices such as the battery
charger and Mapphone-specific ADC/regulator/USB-PHY. By mapping to
CPCAP_DEFAULT, the MFD core uses generic compatible strings (e.g.,
"motorola,cpcap-adc" instead of "motorola,mapphone-cpcap-adc") and entirely
omits the charger. As a result, the child devices fail to match their DT nodes,
leaving them without of_node pointers and breaking critical functionality.
Additionally, could the complete removal of the "st,6556002" compatible string
(mentioned in the commit message) break devices relying on it?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260520182124.117863-1-clamor95@gmail.com?part=5
^ permalink raw reply
* Re: Mismatched product ids for the ASUS ROG RAIKIRI PRO
From: opinijm @ 2026-05-20 19:13 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: linux-input, linux-kernel, torvalds, Luke D. Jones
In-Reply-To: <qXthrkx15NUzfYKQebMAJLqDmGXrsQJYTPFko4SvPAd--C6OBfBLWc0raywIArf-MoxJlRLg1XJna4AWORI1mmYAe2eh6eaL9K15Z0zTgMQ=@provdh.com>
On Wednesday, May 20th, 2026 at 3:06 PM, opinijm@provdh.com <opinijm@provdh.com> wrote:
>
> On Tuesday, May 19th, 2026 at 5:19 PM, Dmitry Torokhov <dmitry.torokhov@gmail.com> wrote:
>
> > Hi Justin,
> >
> > On Tue, May 19, 2026 at 01:37:59PM -0400, Justin Opini wrote:
> > > Hey Dimity,
> > >
> > > I had a question on the product id,
> > > { 0x0b05, 0x1abb, "ASUS ROG RAIKIRI PRO", 0, XTYPE_XBOXONE },
> > >
> > > This doesn’t match both my devices so I was wondering if somehow we
> > > have similar named devices with need for different product ids or if
> > > there was a mistake in the original commit?
> > >
> > > My relevant entries from lsusb are
> > > Bus 001 Device 002: ID 0b05:1a3c ASUSTek Computer, Inc. ROG RAIKIRI PRO
> > > Bus 001 Device 003: ID 0b05:1a3c ASUSTek Computer, Inc. ROG RAIKIRI PRO
> > >
> > > On my system I have ended up using this udev rule for quite some time
> > > ACTION=="add", ATTRS{idVendor}=="0b05", ATTRS{idProduct}=="1a3c", GROUP="input", MODE="0660", TAG+="uaccess", TAG+="seat", RUN+="/bin/sh -c 'echo 0b05 1a3c > /sys/bus/usb/drivers/xpad/new_id'"
> >
> > I am CC-ing Luke who added this VID/PID comboi to double check, but it
> > looks like there are many variants of this controller using the same
> > "ROG RAIKIRI PRO" name. For example
> > https://github.com/atar-axis/xpadneo/issues/612 talks about
> > 0x0b05/0x1abd.
> >
>
> Ah i was thinking about this more. The device has 3 modes of connection, there is Bluetooth(on the Github tracker), and 2.4GHz via USB receiver(which is what I use) as well as USB directly to the device. Not use if this is enough to introduce variants, but I thought it was worth thinking out aloud. Maybe Luke could chime in on usage? In any case is a patch appropriate here to introduce variant?
Connected via USB I get,
Bus 003 Device 004: ID 0b05:1abb ASUSTek Computer, Inc. ROG RAIKIRI PRO
I can't test Bluetooth because I have a motherboard that doesn't have a supported driver yet.
>
> > Thanks.
> >
> > --
> > Dmitry
> >
^ permalink raw reply
* Re: Mismatched product ids for the ASUS ROG RAIKIRI PRO
From: opinijm @ 2026-05-20 19:06 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: linux-input, linux-kernel, torvalds, Luke D. Jones
In-Reply-To: <agzSfM3TH8Pg0M4I@google.com>
On Tuesday, May 19th, 2026 at 5:19 PM, Dmitry Torokhov <dmitry.torokhov@gmail.com> wrote:
> Hi Justin,
>
> On Tue, May 19, 2026 at 01:37:59PM -0400, Justin Opini wrote:
> > Hey Dimity,
> >
> > I had a question on the product id,
> > { 0x0b05, 0x1abb, "ASUS ROG RAIKIRI PRO", 0, XTYPE_XBOXONE },
> >
> > This doesn’t match both my devices so I was wondering if somehow we
> > have similar named devices with need for different product ids or if
> > there was a mistake in the original commit?
> >
> > My relevant entries from lsusb are
> > Bus 001 Device 002: ID 0b05:1a3c ASUSTek Computer, Inc. ROG RAIKIRI PRO
> > Bus 001 Device 003: ID 0b05:1a3c ASUSTek Computer, Inc. ROG RAIKIRI PRO
> >
> > On my system I have ended up using this udev rule for quite some time
> > ACTION=="add", ATTRS{idVendor}=="0b05", ATTRS{idProduct}=="1a3c", GROUP="input", MODE="0660", TAG+="uaccess", TAG+="seat", RUN+="/bin/sh -c 'echo 0b05 1a3c > /sys/bus/usb/drivers/xpad/new_id'"
>
> I am CC-ing Luke who added this VID/PID comboi to double check, but it
> looks like there are many variants of this controller using the same
> "ROG RAIKIRI PRO" name. For example
> https://github.com/atar-axis/xpadneo/issues/612 talks about
> 0x0b05/0x1abd.
>
Ah i was thinking about this more. The device has 3 modes of connection, there is Bluetooth(on the Github tracker), and 2.4GHz via USB receiver(which is what I use) as well as USB directly to the device. Not use if this is enough to introduce variants, but I thought it was worth thinking out aloud. Maybe Luke could chime in on usage? In any case is a patch appropriate here to introduce variant?
> Thanks.
>
> --
> Dmitry
>
^ permalink raw reply
* Re: [PATCH v6 3/6] dt-bindings: mfd: motorola-cpcap: convert to DT schema
From: sashiko-bot @ 2026-05-20 18:52 UTC (permalink / raw)
To: Svyatoslav Ryhel; +Cc: devicetree, linux-input, robh, conor+dt, dmitry.torokhov
In-Reply-To: <20260520182124.117863-4-clamor95@gmail.com>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] The YAML conversion introduces structural differences and omits previously required properties, causing schema validation to fail for existing in-tree device trees.
- [Medium] Incorrect use of 'additionalProperties: false' in conjunction with inherited schemas via 'allOf: - $ref', blocking standard SPI properties.
- [Medium] The `spi-cs-high` property was required in the original TXT binding but is missing from the YAML `required` list.
- [Medium] The YAML binding strictly requires exactly two compatible strings, contradicting the original TXT binding which allowed 'One or both'.
--
commit a23d8229dfec6cdc65afe36d12b859535df8cfc9
Author: Svyatoslav Ryhel <clamor95@gmail.com>
dt-bindings: mfd: motorola-cpcap: convert to DT schema
Convert devicetree bindings for the Motorola CPCAP MFD from TXT to YAML.
> diff --git a/Documentation/devicetree/bindings/mfd/motorola,cpcap.yaml b/Documentation/devicetree/bindings/mfd/motorola,cpcap.yaml
> new file mode 100644
> index 0000000000000..76705ea56805a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mfd/motorola,cpcap.yaml
> @@ -0,0 +1,403 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/mfd/motorola,cpcap.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Motorola CPCAP PMIC MFD
> +
> +maintainers:
> + - Svyatoslav Ryhel <clamor95@gmail.com>
> +
> +allOf:
> + - $ref: /schemas/spi/spi-peripheral-props.yaml#
> +
> +properties:
> + compatible:
> + items:
> + - const: motorola,cpcap
> + - const: st,6556002
[Severity: Medium]
Does this strict array configuration restrict compatible strings too much?
The original txt binding indicated that "One or both" strings were
acceptable, but this yaml structure enforces exactly both strings in this
specific order. Could this cause a regression for hardware implementations
that only use a single compatible string, which the driver supports?
> +
> + reg:
> + maxItems: 1
[Severity: High]
Are #address-cells and #size-cells missing from this top-level node?
The original txt binding explicitly required these, and existing in-tree
device trees (like arch/arm/boot/dts/ti/omap/motorola-cpcap-mapphone.dtsi)
use them. With additionalProperties: false set, will this cause a regression
where existing valid dts files fail validation?
[ ... ]
> + audio-codec:
> + type: object
> + additionalProperties: false
> +
> + properties:
[ ... ]
> + ports:
> + $ref: /schemas/graph.yaml#/properties/ports
> +
> + properties:
> + port@0:
> + $ref: /schemas/graph.yaml#/properties/port
> + description: port connected to the Stereo HiFi DAC
> +
> + port@1:
> + $ref: /schemas/graph.yaml#/properties/port
> + description: port connected to the Voice DAC
> +
> + required:
> + - port@0
> + - port@1
[Severity: High]
Does this structurally conflict with existing in-tree device trees?
The new schema requires a ports container for the audio codec, but existing
in-tree device trees define port@0 and port@1 directly under the audio-codec
node without a wrapper. Since no patch in this series updates the
corresponding dtsi files, won't this cause a regression where existing device
trees are incorrectly rejected?
[ ... ]
> + key-power:
> + $ref: /schemas/input/motorola,cpcap-pwrbutton.yaml#
[Severity: High]
Will this correctly match the existing device tree nodes?
The schema expects the subnode to be named key-power, but existing in-tree
device trees use the name button (e.g., power_button: button { ... }).
This mismatch will likely cause a regression for the subnode validation.
[ ... ]
> +required:
> + - compatible
> + - reg
> + - interrupts
> + - interrupt-controller
> + - "#interrupt-cells"
> + - spi-max-frequency
[Severity: Medium]
Should spi-cs-high be included in this required list?
The original txt binding explicitly listed spi-cs-high as a required property,
and the pmic physically requires an active-high spi chip select to function.
If it is omitted from this list, could a device tree missing this hardware
constraint incorrectly pass schema validation?
> +
> +additionalProperties: false
[Severity: Medium]
Should this use unevaluatedProperties: false instead of
additionalProperties: false?
When inheriting from another schema like spi-peripheral-props.yaml via an
allOf reference, additionalProperties: false will reject the inherited
properties unless they are manually redefined in this file. Using
unevaluatedProperties would properly handle the inherited spi properties
and remove the need to manually declare spi-cs-high, spi-cpol, and
spi-cpha above.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260520182124.117863-1-clamor95@gmail.com?part=3
^ permalink raw reply
* [PATCH 10/10] gpiolib: turn off legacy interface by default
From: Arnd Bergmann @ 2026-05-20 18:38 UTC (permalink / raw)
To: linux-gpio
Cc: linux-kernel, Arnd Bergmann, Christian Lamparter, Johannes Berg,
Aaro Koskinen, Andreas Kemnade, Kevin Hilman, Roger Quadros,
Tony Lindgren, Thomas Bogendoerfer, John Paul Adrian Glaubitz,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
H. Peter Anvin, Linus Walleij, Bartosz Golaszewski,
Dmitry Torokhov, Lee Jones, Pavel Machek, Matti Vaittinen,
Florian Fainelli, Jonas Gorski, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
linux-wireless, linux-omap, linux-arm-kernel, linux-mips,
linux-sh, linux-input, linux-leds, netdev
In-Reply-To: <20260520183815.2510387-1-arnd@kernel.org>
From: Arnd Bergmann <arnd@arndb.de>
All users of the legacy interface now select CONFIG_GPIOLIB_LEGACY,
so it can be turned off by default and only get built on platforms
that still have one unconverted driver.
Allow turning it on manually for compile testing, in order to keep
the build coverage of the legacy drivers in allmodconfig and
randconfig.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
drivers/gpio/Kconfig | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
This patch depends on patches 1 through 9 to be applied first.
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 00fcab5d09a4..eec17089eaa6 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -4,7 +4,14 @@
#
config GPIOLIB_LEGACY
- def_bool y
+ bool "Legacy GPIO interfaces" if COMPILE_TEST
+ help
+ There are a few legacy platforms that use the traditional GPIO
+ number based interfaces instead of GPIO descriptors.
+ Say Y here to enable build testing drivers that are specific
+ to those platforms.
+
+ If unsure, say N.
config HAVE_SHARED_GPIOS
bool
--
2.39.5
^ permalink raw reply related
* [PATCH 09/10] [v6 omap] ARM: dts: omap2: add stlc4560 spi-wireless node
From: Arnd Bergmann @ 2026-05-20 18:38 UTC (permalink / raw)
To: linux-gpio
Cc: linux-kernel, Arnd Bergmann, Christian Lamparter, Johannes Berg,
Aaro Koskinen, Andreas Kemnade, Kevin Hilman, Roger Quadros,
Tony Lindgren, Thomas Bogendoerfer, John Paul Adrian Glaubitz,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
H. Peter Anvin, Linus Walleij, Bartosz Golaszewski,
Dmitry Torokhov, Lee Jones, Pavel Machek, Matti Vaittinen,
Florian Fainelli, Jonas Gorski, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
linux-wireless, linux-omap, linux-arm-kernel, linux-mips,
linux-sh, linux-input, linux-leds, netdev, Krzysztof Kozlowski
In-Reply-To: <20260520183815.2510387-1-arnd@kernel.org>
From: Arnd Bergmann <arnd@arndb.de>
Converted from the platform_device creation in board-n8x0.c.
Link: https://lore.kernel.org/all/20230314163201.955689-1-arnd@kernel.org/
Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
v6: no changes
v1 through v5: adaptations that correspond to the binding updates
---
arch/arm/boot/dts/ti/omap/omap2.dtsi | 4 ++++
arch/arm/boot/dts/ti/omap/omap2420-n8x0-common.dtsi | 12 ++++++++++++
2 files changed, 16 insertions(+)
diff --git a/arch/arm/boot/dts/ti/omap/omap2.dtsi b/arch/arm/boot/dts/ti/omap/omap2.dtsi
index afabb36a8ac1..fdc1790adf43 100644
--- a/arch/arm/boot/dts/ti/omap/omap2.dtsi
+++ b/arch/arm/boot/dts/ti/omap/omap2.dtsi
@@ -129,6 +129,8 @@ i2c2: i2c@48072000 {
};
mcspi1: spi@48098000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
compatible = "ti,omap2-mcspi";
ti,hwmods = "mcspi1";
reg = <0x48098000 0x100>;
@@ -140,6 +142,8 @@ mcspi1: spi@48098000 {
};
mcspi2: spi@4809a000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
compatible = "ti,omap2-mcspi";
ti,hwmods = "mcspi2";
reg = <0x4809a000 0x100>;
diff --git a/arch/arm/boot/dts/ti/omap/omap2420-n8x0-common.dtsi b/arch/arm/boot/dts/ti/omap/omap2420-n8x0-common.dtsi
index 63b0b4921e4e..fe9dd8bbfc85 100644
--- a/arch/arm/boot/dts/ti/omap/omap2420-n8x0-common.dtsi
+++ b/arch/arm/boot/dts/ti/omap/omap2420-n8x0-common.dtsi
@@ -109,3 +109,15 @@ partition@5 {
};
};
};
+
+&mcspi2 {
+ status = "okay";
+
+ wifi@0 {
+ reg = <0>;
+ compatible = "st,stlc4560";
+ spi-max-frequency = <48000000>;
+ interrupts-extended = <&gpio3 23 IRQ_TYPE_EDGE_RISING>;
+ powerdown-gpios = <&gpio4 1 GPIO_ACTIVE_LOW>; /* gpio 97 */
+ };
+};
--
2.39.5
^ permalink raw reply related
* [PATCH 08/10] [v6 net-next] p54spi: convert to devicetree
From: Arnd Bergmann @ 2026-05-20 18:38 UTC (permalink / raw)
To: linux-gpio
Cc: linux-kernel, Arnd Bergmann, Christian Lamparter, Johannes Berg,
Aaro Koskinen, Andreas Kemnade, Kevin Hilman, Roger Quadros,
Tony Lindgren, Thomas Bogendoerfer, John Paul Adrian Glaubitz,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
H. Peter Anvin, Linus Walleij, Bartosz Golaszewski,
Dmitry Torokhov, Lee Jones, Pavel Machek, Matti Vaittinen,
Florian Fainelli, Jonas Gorski, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
linux-wireless, linux-omap, linux-arm-kernel, linux-mips,
linux-sh, linux-input, linux-leds, netdev, Christian Lamparter,
Bartosz Golaszewski
In-Reply-To: <20260520183815.2510387-1-arnd@kernel.org>
From: Arnd Bergmann <arnd@arndb.de>
The Prism54 SPI driver hardcodes GPIO numbers and expects users to
pass them as module parameters, apparently a relic from its life as a
staging driver. This works because there is only one user, the Nokia
N8x0 tablet.
Convert this to the gpio descriptor interface and DT based probing
to improve this and simplify the code at the same time.
Acked-by: Christian Lamparter <chunkeey@gmail.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
v6:
- no changes. Sashiko comments about incorrect on-stack SPI transfers
and error handling in the IRQ registration turned out to be
irrelevant for this submission.
v5:
- fix irq assignment # https://sashiko.dev/#/patchset/20260430081242.3686993-1-arnd%40kernel.org
v4:
- make gpio line optional again
- fix EPROBE_DEFER handling
- match only st,stlc4560 compatible value, with binding change
v3:
- rebase an older patch
---
arch/arm/mach-omap2/board-n8x0.c | 18 ------
drivers/net/wireless/intersil/p54/p54spi.c | 67 ++++++++--------------
drivers/net/wireless/intersil/p54/p54spi.h | 3 +
3 files changed, 26 insertions(+), 62 deletions(-)
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
index 969265d5d5c6..d9acd32c5457 100644
--- a/arch/arm/mach-omap2/board-n8x0.c
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -20,7 +20,6 @@
#include <linux/spi/spi.h>
#include <linux/usb/musb.h>
#include <linux/mmc/host.h>
-#include <linux/platform_data/spi-omap2-mcspi.h>
#include <linux/platform_data/mmc-omap.h>
#include <linux/mfd/menelaus.h>
@@ -106,21 +105,6 @@ static void __init n8x0_usb_init(void) {}
#endif /*CONFIG_USB_MUSB_TUSB6010 */
-
-static struct omap2_mcspi_device_config p54spi_mcspi_config = {
- .turbo_mode = 0,
-};
-
-static struct spi_board_info n800_spi_board_info[] __initdata = {
- {
- .modalias = "p54spi",
- .bus_num = 2,
- .chip_select = 0,
- .max_speed_hz = 48000000,
- .controller_data = &p54spi_mcspi_config,
- },
-};
-
#if defined(CONFIG_MENELAUS) && IS_ENABLED(CONFIG_MMC_OMAP)
/*
@@ -524,7 +508,5 @@ omap_late_initcall(n8x0_late_initcall);
void * __init n8x0_legacy_init(void)
{
board_check_revision();
- spi_register_board_info(n800_spi_board_info,
- ARRAY_SIZE(n800_spi_board_info));
return &mmc1_data;
}
diff --git a/drivers/net/wireless/intersil/p54/p54spi.c b/drivers/net/wireless/intersil/p54/p54spi.c
index 9d66dcae54e0..d18be2545028 100644
--- a/drivers/net/wireless/intersil/p54/p54spi.c
+++ b/drivers/net/wireless/intersil/p54/p54spi.c
@@ -8,6 +8,7 @@
*/
#include <linux/module.h>
+#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/firmware.h>
@@ -15,7 +16,7 @@
#include <linux/irq.h>
#include <linux/spi/spi.h>
#include <linux/etherdevice.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/slab.h>
#include "p54spi.h"
@@ -30,19 +31,6 @@
MODULE_FIRMWARE("3826.arm");
MODULE_FIRMWARE("3826.eeprom");
-/* gpios should be handled in board files and provided via platform data,
- * but because it's currently impossible for p54spi to have a header file
- * in include/linux, let's use module parameters for now
- */
-
-static int p54spi_gpio_power = 97;
-module_param(p54spi_gpio_power, int, 0444);
-MODULE_PARM_DESC(p54spi_gpio_power, "gpio number for power line");
-
-static int p54spi_gpio_irq = 87;
-module_param(p54spi_gpio_irq, int, 0444);
-MODULE_PARM_DESC(p54spi_gpio_irq, "gpio number for irq line");
-
static void p54spi_spi_read(struct p54s_priv *priv, u8 address,
void *buf, size_t len)
{
@@ -262,14 +250,14 @@ static int p54spi_upload_firmware(struct ieee80211_hw *dev)
static void p54spi_power_off(struct p54s_priv *priv)
{
- disable_irq(gpio_to_irq(p54spi_gpio_irq));
- gpio_set_value(p54spi_gpio_power, 0);
+ disable_irq(priv->irq);
+ gpiod_set_value(priv->gpio_powerdown, 1);
}
static void p54spi_power_on(struct p54s_priv *priv)
{
- gpio_set_value(p54spi_gpio_power, 1);
- enable_irq(gpio_to_irq(p54spi_gpio_irq));
+ gpiod_set_value(priv->gpio_powerdown, 0);
+ enable_irq(priv->irq);
/* need to wait a while before device can be accessed, the length
* is just a guess
@@ -608,31 +596,20 @@ static int p54spi_probe(struct spi_device *spi)
goto err_free;
}
- ret = gpio_request(p54spi_gpio_power, "p54spi power");
- if (ret < 0) {
- dev_err(&priv->spi->dev, "power GPIO request failed: %d", ret);
+ priv->gpio_powerdown = gpiod_get_optional(&spi->dev, "powerdown", GPIOD_OUT_HIGH);
+ if (IS_ERR(priv->gpio_powerdown)) {
+ ret = dev_err_probe(&priv->spi->dev, PTR_ERR(priv->gpio_powerdown),
+ "powerdown GPIO request failed\n");
goto err_free;
}
- ret = gpio_request(p54spi_gpio_irq, "p54spi irq");
- if (ret < 0) {
- dev_err(&priv->spi->dev, "irq GPIO request failed: %d", ret);
- goto err_free_gpio_power;
- }
-
- gpio_direction_output(p54spi_gpio_power, 0);
- gpio_direction_input(p54spi_gpio_irq);
-
- ret = request_irq(gpio_to_irq(p54spi_gpio_irq),
- p54spi_interrupt, IRQF_NO_AUTOEN, "p54spi",
- priv->spi);
+ ret = request_irq(spi->irq, p54spi_interrupt, IRQF_NO_AUTOEN, "p54spi", priv->spi);
if (ret < 0) {
dev_err(&priv->spi->dev, "request_irq() failed");
- goto err_free_gpio_irq;
+ goto err_free_gpio_power;
}
- irq_set_irq_type(gpio_to_irq(p54spi_gpio_irq), IRQ_TYPE_EDGE_RISING);
-
+ priv->irq = spi->irq;
INIT_WORK(&priv->work, p54spi_work);
init_completion(&priv->fw_comp);
INIT_LIST_HEAD(&priv->tx_pending);
@@ -659,11 +636,9 @@ static int p54spi_probe(struct spi_device *spi)
err_free_common:
release_firmware(priv->firmware);
- free_irq(gpio_to_irq(p54spi_gpio_irq), spi);
-err_free_gpio_irq:
- gpio_free(p54spi_gpio_irq);
+ free_irq(priv->irq, spi);
err_free_gpio_power:
- gpio_free(p54spi_gpio_power);
+ gpiod_put(priv->gpio_powerdown);
err_free:
p54_free_common(priv->hw);
return ret;
@@ -675,10 +650,8 @@ static void p54spi_remove(struct spi_device *spi)
p54_unregister_common(priv->hw);
- free_irq(gpio_to_irq(p54spi_gpio_irq), spi);
-
- gpio_free(p54spi_gpio_power);
- gpio_free(p54spi_gpio_irq);
+ free_irq(priv->irq, spi);
+ gpiod_put(priv->gpio_powerdown);
release_firmware(priv->firmware);
mutex_destroy(&priv->mutex);
@@ -686,10 +659,16 @@ static void p54spi_remove(struct spi_device *spi)
p54_free_common(priv->hw);
}
+static const struct of_device_id p54spi_of_ids[] = {
+ { .compatible = "st,stlc4560", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, p54spi_of_ids);
static struct spi_driver p54spi_driver = {
.driver = {
.name = "p54spi",
+ .of_match_table = p54spi_of_ids,
},
.probe = p54spi_probe,
diff --git a/drivers/net/wireless/intersil/p54/p54spi.h b/drivers/net/wireless/intersil/p54/p54spi.h
index e5619a13fd61..118785cc635a 100644
--- a/drivers/net/wireless/intersil/p54/p54spi.h
+++ b/drivers/net/wireless/intersil/p54/p54spi.h
@@ -107,6 +107,9 @@ struct p54s_priv {
enum fw_state fw_state;
const struct firmware *firmware;
+
+ struct gpio_desc *gpio_powerdown;
+ int irq;
};
#endif /* P54SPI_H */
--
2.39.5
^ permalink raw reply related
* [PATCH 07/10] [v6 net-next] dt-bindings: net: add st,stlc4560/p54spi binding
From: Arnd Bergmann @ 2026-05-20 18:38 UTC (permalink / raw)
To: linux-gpio
Cc: linux-kernel, Arnd Bergmann, Christian Lamparter, Johannes Berg,
Aaro Koskinen, Andreas Kemnade, Kevin Hilman, Roger Quadros,
Tony Lindgren, Thomas Bogendoerfer, John Paul Adrian Glaubitz,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
H. Peter Anvin, Linus Walleij, Bartosz Golaszewski,
Dmitry Torokhov, Lee Jones, Pavel Machek, Matti Vaittinen,
Florian Fainelli, Jonas Gorski, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
linux-wireless, linux-omap, linux-arm-kernel, linux-mips,
linux-sh, linux-input, linux-leds, netdev, Christian Lamparter,
Conor Dooley
In-Reply-To: <20260520183815.2510387-1-arnd@kernel.org>
From: Arnd Bergmann <arnd@arndb.de>
The SPI version of Prism54 was sold under a couple of different
names and supported by the Linux p54spi driver, but there was
never a DT binding for it.
Document the four known names of this device and the properties
that are sufficient for its use on the Nokia N8x0 tablet.
As I don't have this hardware or documentation for it, this is
purely based on existing usage in the driver.
Link: https://lore.kernel.org/all/e8dc9acb-6f85-e0a9-a145-d101ca6da201@gmail.com/
Acked-by: Christian Lamparter <chunkeey@gmail.com>
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
v6: no changes
v5: fix name in MAINTAINERS file
v4: renamed file to st,stlc4560, matching the primary compatible string
require st,stlc4560 string
---
.../bindings/net/wireless/st,stlc4560.yaml | 61 +++++++++++++++++++
MAINTAINERS | 1 +
2 files changed, 62 insertions(+)
create mode 100644 Documentation/devicetree/bindings/net/wireless/st,stlc4560.yaml
diff --git a/Documentation/devicetree/bindings/net/wireless/st,stlc4560.yaml b/Documentation/devicetree/bindings/net/wireless/st,stlc4560.yaml
new file mode 100644
index 000000000000..a32265c07350
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/wireless/st,stlc4560.yaml
@@ -0,0 +1,61 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/wireless/st,stlc4560.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ST/Intersil/Conexant stlc45xx/p54spi/cx3110x SPI wireless device
+
+maintainers:
+ - Christian Lamparter <chunkeey@gmail.com>
+
+description:
+ The SPI variant of the Intersil Prism54 wireless device was sold
+ under a variety of names, including Conexant CX3110x and
+ ST Microelectronics STLC4560.
+
+allOf:
+ - $ref: ieee80211.yaml#
+ - $ref: /schemas/spi/spi-peripheral-props.yaml#
+
+properties:
+ compatible:
+ oneOf:
+ - const: st,stlc4560
+ - items:
+ - enum:
+ - cnxt,3110x
+ - isil,p54spi
+ - st,stlc4550
+ - const: st,stlc4560
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ powerdown-gpios:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - interrupts
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ spi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ wifi@0 {
+ compatible = "st,stlc4560";
+ reg = <0>;
+ spi-max-frequency = <48000000>;
+ interrupts-extended = <&gpio 23>;
+ powerdown-gpios = <&gpio 1>;
+ };
+ };
diff --git a/MAINTAINERS b/MAINTAINERS
index 8063cb56feef..93cf1fb72357 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -20306,6 +20306,7 @@ M: Christian Lamparter <chunkeey@googlemail.com>
L: linux-wireless@vger.kernel.org
S: Maintained
W: https://wireless.wiki.kernel.org/en/users/Drivers/p54
+F: Documentation/devicetree/bindings/net/wireless/st,stlc4560.yaml
F: drivers/net/wireless/intersil/
PACKET SOCKETS
--
2.39.5
^ permalink raw reply related
* [PATCH 06/10] [v4] leds: gpio: make legacy gpiolib interface optional
From: Arnd Bergmann @ 2026-05-20 18:38 UTC (permalink / raw)
To: linux-gpio
Cc: linux-kernel, Arnd Bergmann, Christian Lamparter, Johannes Berg,
Aaro Koskinen, Andreas Kemnade, Kevin Hilman, Roger Quadros,
Tony Lindgren, Thomas Bogendoerfer, John Paul Adrian Glaubitz,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
H. Peter Anvin, Linus Walleij, Bartosz Golaszewski,
Dmitry Torokhov, Lee Jones, Pavel Machek, Matti Vaittinen,
Florian Fainelli, Jonas Gorski, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
linux-wireless, linux-omap, linux-arm-kernel, linux-mips,
linux-sh, linux-input, linux-leds, netdev, Bartosz Golaszewski,
Andy Shevchenko
In-Reply-To: <20260520183815.2510387-1-arnd@kernel.org>
From: Arnd Bergmann <arnd@arndb.de>
There are still a handful of ancient mips/armv5/sh boards that use the
gpio_led:gpio member to pass an old-style gpio number, but all modern
users have been converted to gpio descriptors.
While the CONFIG_GPIOLIB_LEGACY option that guards devm_gpio_request_one()
and related helpers is currently turned on in all kernel builds,
the plan is to only enable it on the few platforms that actually
pass gpio numbers in any platform_data.
Split out the legacy portion of the platform_data handling into a custom
helper function that is guarded with in #ifdef block, to allow the
the leds-gpio driver to compile cleanly when CONFIG_GPIOLIB_LEGACY
gets turned off. Once the last user is converted, this function can
be removed.
Link: https://lore.kernel.org/all/e9252384-a55c-4a91-9c61-06e05a0b2ce4@app.fastmail.com/
Reviewed-by: Linus Walleij <linusw@kernel.org>
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
v4: whitespace changes only
v3: simplify gpio_led_get_gpiod
v2: rework a little bit to keep the legacy code path more separate,
extend changelog description
Related to this, we may also want to remove support for passing
a gpio descriptor in the ->gpiod flag. The only user doing this
at the moment was introduced in commit 1892e87a3e91 ("powerpc/warp:
switch to using gpiod API").
---
drivers/leds/leds-gpio.c | 51 ++++++++++++++++++++++++++--------------
include/linux/leds.h | 2 ++
2 files changed, 36 insertions(+), 17 deletions(-)
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
index a3428b22de3a..d6a0369eeb92 100644
--- a/drivers/leds/leds-gpio.c
+++ b/drivers/leds/leds-gpio.c
@@ -212,7 +212,6 @@ static struct gpio_desc *gpio_led_get_gpiod(struct device *dev, int idx,
const struct gpio_led *template)
{
struct gpio_desc *gpiod;
- int ret;
/*
* This means the LED does not come from the device tree
@@ -221,18 +220,30 @@ static struct gpio_desc *gpio_led_get_gpiod(struct device *dev, int idx,
* the GPIO from there.
*/
gpiod = devm_gpiod_get_index_optional(dev, NULL, idx, GPIOD_OUT_LOW);
- if (IS_ERR(gpiod))
- return gpiod;
- if (gpiod) {
+ if (!IS_ERR(gpiod))
gpiod_set_consumer_name(gpiod, template->name);
- return gpiod;
- }
- /*
- * This is the legacy code path for platform code that
- * still uses GPIO numbers. Ultimately we would like to get
- * rid of this block completely.
- */
+ return gpiod;
+}
+
+#ifdef CONFIG_GPIOLIB_LEGACY
+/*
+ * This is the legacy code path for platform code that still uses
+ * GPIO numbers, mainly MIPS and SuperH board files.
+ * Ultimately we would like to get rid of this block completely.
+ *
+ * ppc44x-warp sets the template->gpiod directly instead of
+ * adding a lookup table or device properties. This is not
+ * much better.
+ */
+static struct gpio_desc *gpio_led_get_legacy_gpiod(struct device *dev, int idx,
+ const struct gpio_led *template)
+{
+ struct gpio_desc *gpiod;
+ int ret;
+
+ if (template->gpiod)
+ return template->gpiod;
/* skip leds that aren't available */
if (!gpio_is_valid(template->gpio))
@@ -252,6 +263,13 @@ static struct gpio_desc *gpio_led_get_gpiod(struct device *dev, int idx,
return gpiod;
}
+#else
+static struct gpio_desc *gpio_led_get_legacy_gpiod(struct device *dev, int idx,
+ const struct gpio_led *template)
+{
+ return template->gpiod ?: ERR_PTR(-ENOENT);
+}
+#endif
static int gpio_led_probe(struct platform_device *pdev)
{
@@ -270,14 +288,13 @@ static int gpio_led_probe(struct platform_device *pdev)
const struct gpio_led *template = &pdata->leds[i];
struct gpio_led_data *led_dat = &priv->leds[i];
- if (template->gpiod)
- led_dat->gpiod = template->gpiod;
- else
+ led_dat->gpiod = gpio_led_get_gpiod(dev, i, template);
+ if (!led_dat->gpiod)
led_dat->gpiod =
- gpio_led_get_gpiod(dev, i, template);
+ gpio_led_get_legacy_gpiod(dev, i, template);
if (IS_ERR(led_dat->gpiod)) {
- dev_info(dev, "Skipping unavailable LED gpio %d (%s)\n",
- template->gpio, template->name);
+ dev_info(dev, "Skipping unavailable LED gpio %s\n",
+ template->name);
continue;
}
diff --git a/include/linux/leds.h b/include/linux/leds.h
index b16b803cc1ac..e646bffcd8e7 100644
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
@@ -676,8 +676,10 @@ typedef int (*gpio_blink_set_t)(struct gpio_desc *desc, int state,
struct gpio_led {
const char *name;
const char *default_trigger;
+#ifdef CONFIG_GPIOLIB_LEGACY
unsigned gpio;
unsigned active_low : 1;
+#endif
unsigned retain_state_suspended : 1;
unsigned panic_indicator : 1;
unsigned default_state : 2;
--
2.39.5
^ permalink raw reply related
* [PATCH 05/10] [v2] mips: select legacy gpiolib interfaces where used
From: Arnd Bergmann @ 2026-05-20 18:38 UTC (permalink / raw)
To: linux-gpio
Cc: linux-kernel, Arnd Bergmann, Christian Lamparter, Johannes Berg,
Aaro Koskinen, Andreas Kemnade, Kevin Hilman, Roger Quadros,
Tony Lindgren, Thomas Bogendoerfer, John Paul Adrian Glaubitz,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
H. Peter Anvin, Linus Walleij, Bartosz Golaszewski,
Dmitry Torokhov, Lee Jones, Pavel Machek, Matti Vaittinen,
Florian Fainelli, Jonas Gorski, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
linux-wireless, linux-omap, linux-arm-kernel, linux-mips,
linux-sh, linux-input, linux-leds, netdev, Bartosz Golaszewski
In-Reply-To: <20260520183815.2510387-1-arnd@kernel.org>
From: Arnd Bergmann <arnd@arndb.de>
A few old machines have not been converted away from the old-style
gpiolib interfaces. Make these select the new CONFIG_GPIOLIB_LEGACY
symbol so the code still works where it is needed but can be left
out otherwise.
This is the list of all gpio_request() calls in mips:
arch/mips/alchemy/devboards/db1000.c: gpio_request(19, "sd0_cd");
arch/mips/alchemy/devboards/db1000.c: gpio_request(20, "sd1_cd");
arch/mips/alchemy/devboards/db1200.c: gpio_request(215, "otg-vbus");
arch/mips/bcm47xx/workarounds.c: err = gpio_request_one(usb_power, GPIOF_OUT_INIT_HIGH, "usb_power");
arch/mips/bcm63xx/boards/board_bcm963xx.c: gpio_request_one(board.ephy_reset_gpio,
arch/mips/txx9/rbtx4927/setup.c: gpio_request(15, "sio-dtr");
Most of these should be easy enough to change to modern gpio descriptors
or remove if they are no longer in use.
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
v2: no changes. There was no discussion on this, but the patch
has so far not made it into the linux-mips tree, so I'm including
it for completeness.
---
arch/mips/Kconfig | 5 +++++
arch/mips/alchemy/Kconfig | 1 -
arch/mips/txx9/Kconfig | 1 +
3 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 4364f3dba688..b91e62d69a5d 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -206,6 +206,8 @@ config MIPS_ALCHEMY
select CSRC_R4K
select IRQ_MIPS_CPU
select DMA_NONCOHERENT # Au1000,1500,1100 aren't, rest is
+ select GPIOLIB
+ select GPIOLIB_LEGACY
select MIPS_FIXUP_BIGPHYS_ADDR if PCI
select SYS_HAS_CPU_MIPS32_R1
select SYS_SUPPORTS_32BIT_KERNEL
@@ -307,6 +309,7 @@ config BCM47XX
select SYS_HAS_EARLY_PRINTK
select USE_GENERIC_EARLY_PRINTK_8250
select GPIOLIB
+ select GPIOLIB_LEGACY
select LEDS_GPIO_REGISTER
select BCM47XX_NVRAM
select BCM47XX_SPROM
@@ -330,6 +333,7 @@ config BCM63XX
select SYS_HAS_CPU_BMIPS4380
select SWAP_IO_SPACE
select GPIOLIB
+ select GPIOLIB_LEGACY
select MIPS_L1_CACHE_SHIFT_4
select HAVE_LEGACY_CLK
help
@@ -999,6 +1003,7 @@ config MIKROTIK_RB532
select SWAP_IO_SPACE
select BOOT_RAW
select GPIOLIB
+ select GPIOLIB_LEGACY
select MIPS_L1_CACHE_SHIFT_4
help
Support the Mikrotik(tm) RouterBoard 532 series,
diff --git a/arch/mips/alchemy/Kconfig b/arch/mips/alchemy/Kconfig
index 6ca81e1bd35c..cf5ad52c0a0f 100644
--- a/arch/mips/alchemy/Kconfig
+++ b/arch/mips/alchemy/Kconfig
@@ -12,7 +12,6 @@ config MIPS_MTX1
config MIPS_DB1XXX
bool "Alchemy DB1XXX / PB1XXX boards"
- select GPIOLIB
select HAVE_PCI
select HAVE_PATA_PLATFORM
select SYS_SUPPORTS_LITTLE_ENDIAN
diff --git a/arch/mips/txx9/Kconfig b/arch/mips/txx9/Kconfig
index 7335efa4d528..92b759a434c0 100644
--- a/arch/mips/txx9/Kconfig
+++ b/arch/mips/txx9/Kconfig
@@ -37,6 +37,7 @@ config SOC_TX4927
select IRQ_TXX9
select PCI_TX4927
select GPIO_TXX9
+ select GPIOLIB_LEGACY
config SOC_TX4938
bool
--
2.39.5
^ permalink raw reply related
* [PATCH 04/10] [v2] sh: select legacy gpiolib interface
From: Arnd Bergmann @ 2026-05-20 18:38 UTC (permalink / raw)
To: linux-gpio
Cc: linux-kernel, Arnd Bergmann, Christian Lamparter, Johannes Berg,
Aaro Koskinen, Andreas Kemnade, Kevin Hilman, Roger Quadros,
Tony Lindgren, Thomas Bogendoerfer, John Paul Adrian Glaubitz,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
H. Peter Anvin, Linus Walleij, Bartosz Golaszewski,
Dmitry Torokhov, Lee Jones, Pavel Machek, Matti Vaittinen,
Florian Fainelli, Jonas Gorski, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
linux-wireless, linux-omap, linux-arm-kernel, linux-mips,
linux-sh, linux-input, linux-leds, netdev
In-Reply-To: <20260520183815.2510387-1-arnd@kernel.org>
From: Arnd Bergmann <arnd@arndb.de>
Many board files on sh reference the legacy gpiolib interfaces that
are becoming optional. To ensure the boards can keep building, select
CONFIG_GPIOLIB_LEGACY on each of the boards that have one of the
hardcoded calls.
Cc: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
v2: no changes. Adrian said he'll pick it up for 7.2, but so
far the patch is not in linux-next yet, so I'm including it
for completeness here.
---
arch/sh/Kconfig | 1 +
arch/sh/boards/Kconfig | 8 ++++++++
arch/sh/boards/mach-highlander/Kconfig | 1 +
arch/sh/boards/mach-rsk/Kconfig | 3 +++
4 files changed, 13 insertions(+)
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index d5795067befa..d60f1d5a94c0 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -462,6 +462,7 @@ config CPU_SUBTYPE_SHX3
select CPU_SHX3
select GENERIC_CLOCKEVENTS_BROADCAST if SMP
select GPIOLIB
+ select GPIOLIB_LEGACY
select PINCTRL
# SH4AL-DSP Processor Support
diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig
index 1af93be61b1f..d89b74177233 100644
--- a/arch/sh/boards/Kconfig
+++ b/arch/sh/boards/Kconfig
@@ -80,6 +80,7 @@ config SH_7724_SOLUTION_ENGINE
select SOLUTION_ENGINE
depends on CPU_SUBTYPE_SH7724
select GPIOLIB
+ select GPIOLIB_LEGACY
select REGULATOR_FIXED_VOLTAGE if REGULATOR
imply SND_SOC_AK4642 if SND_SIMPLE_CARD
help
@@ -199,6 +200,7 @@ config SH_SH7757LCR
bool "SH7757LCR"
depends on CPU_SUBTYPE_SH7757
select GPIOLIB
+ select GPIOLIB_LEGACY
select REGULATOR_FIXED_VOLTAGE if REGULATOR
config SH_SH7785LCR
@@ -226,6 +228,7 @@ config SH_URQUELL
bool "Urquell"
depends on CPU_SUBTYPE_SH7786
select GPIOLIB
+ select GPIOLIB_LEGACY
select HAVE_PCI
select NO_IOPORT_MAP if !PCI
@@ -233,6 +236,7 @@ config SH_MIGOR
bool "Migo-R"
depends on CPU_SUBTYPE_SH7722
select GPIOLIB
+ select GPIOLIB_LEGACY
select REGULATOR_FIXED_VOLTAGE if REGULATOR
help
Select Migo-R if configuring for the SH7722 Migo-R platform
@@ -242,6 +246,7 @@ config SH_AP325RXA
bool "AP-325RXA"
depends on CPU_SUBTYPE_SH7723
select GPIOLIB
+ select GPIOLIB_LEGACY
select REGULATOR_FIXED_VOLTAGE if REGULATOR
help
Renesas "AP-325RXA" support.
@@ -251,6 +256,7 @@ config SH_KFR2R09
bool "KFR2R09"
depends on CPU_SUBTYPE_SH7724
select GPIOLIB
+ select GPIOLIB_LEGACY
select REGULATOR_FIXED_VOLTAGE if REGULATOR
help
"Kit For R2R for 2009" support.
@@ -259,6 +265,7 @@ config SH_ECOVEC
bool "EcoVec"
depends on CPU_SUBTYPE_SH7724
select GPIOLIB
+ select GPIOLIB_LEGACY
select REGULATOR_FIXED_VOLTAGE if REGULATOR
imply SND_SOC_DA7210 if SND_SIMPLE_CARD
help
@@ -329,6 +336,7 @@ config SH_MAGIC_PANEL_R2
bool "Magic Panel R2"
depends on CPU_SUBTYPE_SH7720
select GPIOLIB
+ select GPIOLIB_LEGACY
select REGULATOR_FIXED_VOLTAGE if REGULATOR
help
Select Magic Panel R2 if configuring for Magic Panel R2.
diff --git a/arch/sh/boards/mach-highlander/Kconfig b/arch/sh/boards/mach-highlander/Kconfig
index b0abd03cac4e..cd3a553ce30c 100644
--- a/arch/sh/boards/mach-highlander/Kconfig
+++ b/arch/sh/boards/mach-highlander/Kconfig
@@ -20,6 +20,7 @@ config SH_R7785RP
bool "R7785RP board support"
depends on CPU_SUBTYPE_SH7785
select GPIOLIB
+ select GPIOLIB_LEGACY
endchoice
diff --git a/arch/sh/boards/mach-rsk/Kconfig b/arch/sh/boards/mach-rsk/Kconfig
index f0299bc4416f..3810937aa5d4 100644
--- a/arch/sh/boards/mach-rsk/Kconfig
+++ b/arch/sh/boards/mach-rsk/Kconfig
@@ -12,16 +12,19 @@ config SH_RSK7201
config SH_RSK7203
bool "RSK7203"
select GPIOLIB
+ select GPIOLIB_LEGACY
depends on CPU_SUBTYPE_SH7203
config SH_RSK7264
bool "RSK2+SH7264"
select GPIOLIB
+ select GPIOLIB_LEGACY
depends on CPU_SUBTYPE_SH7264
config SH_RSK7269
bool "RSK2+SH7269"
select GPIOLIB
+ select GPIOLIB_LEGACY
depends on CPU_SUBTYPE_SH7269
endchoice
--
2.39.5
^ permalink raw reply related
* [PATCH 03/10] [v2] x86/olpc: select GPIOLIB_LEGACY
From: Arnd Bergmann @ 2026-05-20 18:38 UTC (permalink / raw)
To: linux-gpio
Cc: linux-kernel, Arnd Bergmann, Christian Lamparter, Johannes Berg,
Aaro Koskinen, Andreas Kemnade, Kevin Hilman, Roger Quadros,
Tony Lindgren, Thomas Bogendoerfer, John Paul Adrian Glaubitz,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
H. Peter Anvin, Linus Walleij, Bartosz Golaszewski,
Dmitry Torokhov, Lee Jones, Pavel Machek, Matti Vaittinen,
Florian Fainelli, Jonas Gorski, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
linux-wireless, linux-omap, linux-arm-kernel, linux-mips,
linux-sh, linux-input, linux-leds, netdev, Takashi Iwai,
Bartosz Golaszewski
In-Reply-To: <20260520183815.2510387-1-arnd@kernel.org>
From: Arnd Bergmann <arnd@arndb.de>
The OLPC GPIO controller sets up a fixed number space that is used
by at least two drivers:
arch/x86/platform/olpc/olpc-xo1-sci.c: In function 'setup_ec_sci':
arch/x86/platform/olpc/olpc-xo1-sci.c:358:13: error: implicit declaration of function 'gpio_request' [-Wimplicit-function-declaration]
358 | r = gpio_request(OLPC_GPIO_ECSCI, "OLPC-ECSCI");
| ^~~~~~~~~~~~
sound/pci/cs5535audio/cs5535audio_olpc.c: In function 'olpc_analog_input':
sound/pci/cs5535audio/cs5535audio_olpc.c:41:9: error: implicit declaration of function 'gpio_set_value'; did you mean 'gpiod_set_value'? [-Wimplicit-function-declaration]
41 | gpio_set_value(OLPC_GPIO_MIC_AC, on);
The AMD Geode platform that this is based on is now marked as
'Orphaned' in Kconfig, and it is likely that there are no XO1
users on modern kernels, but so far there is no consensus on
removing it entirely.
Select CONFIG_GPIOLIB_LEGACY for this platform and make sure the
sound driver portion cannot be compiled without this.
Acked-by: Borislav Petkov (AMD) <bp@alien8.de>
Acked-by: Takashi Iwai <tiwai@suse.de>
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
v2: update changelog text
---
arch/x86/Kconfig | 1 +
sound/pci/Kconfig | 1 +
2 files changed, 2 insertions(+)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index f24810015234..69089d2f5dad 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2978,6 +2978,7 @@ config OLPC
bool "One Laptop Per Child support"
depends on !X86_PAE
select GPIOLIB
+ select GPIOLIB_LEGACY
select OF
select OF_PROMTREE
select IRQ_DOMAIN
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index e0996a9d90b0..6366f72b3667 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -300,6 +300,7 @@ config SND_CS5535AUDIO
tristate "CS5535/CS5536 Audio"
depends on X86_32 || MIPS || COMPILE_TEST
depends on HAS_IOPORT
+ depends on GPIOLIB_LEGACY || !OLPC
select SND_PCM
select SND_AC97_CODEC
help
--
2.39.5
^ permalink raw reply related
* [PATCH 02/10] [v3] input: gpio-keys: make legacy gpiolib optional
From: Arnd Bergmann @ 2026-05-20 18:38 UTC (permalink / raw)
To: linux-gpio
Cc: linux-kernel, Arnd Bergmann, Christian Lamparter, Johannes Berg,
Aaro Koskinen, Andreas Kemnade, Kevin Hilman, Roger Quadros,
Tony Lindgren, Thomas Bogendoerfer, John Paul Adrian Glaubitz,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
H. Peter Anvin, Linus Walleij, Bartosz Golaszewski,
Dmitry Torokhov, Lee Jones, Pavel Machek, Matti Vaittinen,
Florian Fainelli, Jonas Gorski, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
linux-wireless, linux-omap, linux-arm-kernel, linux-mips,
linux-sh, linux-input, linux-leds, netdev
In-Reply-To: <20260520183815.2510387-1-arnd@kernel.org>
From: Arnd Bergmann <arnd@arndb.de>
Most users of gpio-keys and gpio-keys-polled use modern gpiolib
interfaces, but there are still number of ancient sh, arm32 and x86
machines that have never been converted.
Add an #ifdef block for the parts of the driver that are only used on
those legacy machines.
The two Rohm PMIC drivers use a gpio-keys device without an actual GPIO,
passing an IRQ number instead. In order to keep this working both with
and with CONFIG_GPIOLIB_LEGACY, change the gpio-keys driver to ignore
the gpio number if an IRQ is passed.
Link: https://lore.kernel.org/all/b3c94552-c104-42e3-be15-7e8362e8039e@gmail.com/
Link: https://lore.kernel.org/all/afJXG4_rtaj3l2Dk@google.com/
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
v3: resend
v2: skip the fake GPIO number passing from mfd
The removal of the arm platforms using this is not yet going to happen
for 7.2, and Dmitry's changes for the Rohm drivers have not yet
made it into linux-next as of 2026-05-20, so for the moment I
would still like to see this patch get merged, even if we are
closing in on completely removing the legacy gpio support in
the gpio_keys driver, so we can make CONFIG_GPIOLIB_LEGACY
default-disabled sooner.
---
drivers/input/keyboard/gpio_keys.c | 7 ++++---
drivers/input/keyboard/gpio_keys_polled.c | 2 ++
drivers/mfd/rohm-bd71828.c | 1 -
drivers/mfd/rohm-bd718x7.c | 1 -
include/linux/gpio_keys.h | 2 ++
5 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index e19617485679..d748a54dc51c 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -528,7 +528,8 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
*/
bdata->gpiod = NULL;
}
- } else if (gpio_is_valid(button->gpio)) {
+#ifdef CONFIG_GPIOLIB_LEGACY
+ } else if (!button->irq && gpio_is_valid(button->gpio)) {
/*
* Legacy GPIO number, so request the GPIO here and
* convert it to descriptor.
@@ -546,6 +547,7 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
if (button->active_low ^ gpiod_is_active_low(bdata->gpiod))
gpiod_toggle_active_low(bdata->gpiod);
+#endif
}
if (bdata->gpiod) {
@@ -583,8 +585,7 @@ static int gpio_keys_setup_key(struct platform_device *pdev,
if (irq < 0) {
error = irq;
dev_err_probe(dev, error,
- "Unable to get irq number for GPIO %d\n",
- button->gpio);
+ "Unable to get irq number for GPIO\n");
return error;
}
bdata->irq = irq;
diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c
index e6707d72210e..0ae0e53910ea 100644
--- a/drivers/input/keyboard/gpio_keys_polled.c
+++ b/drivers/input/keyboard/gpio_keys_polled.c
@@ -301,6 +301,7 @@ static int gpio_keys_polled_probe(struct platform_device *pdev)
return dev_err_probe(dev, PTR_ERR(bdata->gpiod),
"failed to get gpio\n");
}
+#ifdef CONFIG_GPIOLIB_LEGACY
} else if (gpio_is_valid(button->gpio)) {
/*
* Legacy GPIO number so request the GPIO here and
@@ -323,6 +324,7 @@ static int gpio_keys_polled_probe(struct platform_device *pdev)
if (button->active_low ^ gpiod_is_active_low(bdata->gpiod))
gpiod_toggle_active_low(bdata->gpiod);
+#endif
}
bdata->last_state = -1;
diff --git a/drivers/mfd/rohm-bd71828.c b/drivers/mfd/rohm-bd71828.c
index a79f354bf5cb..df6dad762ec9 100644
--- a/drivers/mfd/rohm-bd71828.c
+++ b/drivers/mfd/rohm-bd71828.c
@@ -39,7 +39,6 @@
static struct gpio_keys_button button = {
.code = KEY_POWER,
- .gpio = -1,
.type = EV_KEY,
.wakeup = 1,
};
diff --git a/drivers/mfd/rohm-bd718x7.c b/drivers/mfd/rohm-bd718x7.c
index ff714fd4f54d..dd774aa8828b 100644
--- a/drivers/mfd/rohm-bd718x7.c
+++ b/drivers/mfd/rohm-bd718x7.c
@@ -20,7 +20,6 @@
static struct gpio_keys_button button = {
.code = KEY_POWER,
- .gpio = -1,
.type = EV_KEY,
};
diff --git a/include/linux/gpio_keys.h b/include/linux/gpio_keys.h
index 80fa930b04c6..e8d6dc290efb 100644
--- a/include/linux/gpio_keys.h
+++ b/include/linux/gpio_keys.h
@@ -25,7 +25,9 @@ struct device;
*/
struct gpio_keys_button {
unsigned int code;
+#ifdef CONFIG_GPIOLIB_LEGACY
int gpio;
+#endif
int active_low;
const char *desc;
unsigned int type;
--
2.39.5
^ permalink raw reply related
* [PATCH 01/10] [v2] [net-next] net: dsa: b53: hide legacy gpiolib usage on non-mips
From: Arnd Bergmann @ 2026-05-20 18:38 UTC (permalink / raw)
To: linux-gpio
Cc: linux-kernel, Arnd Bergmann, Christian Lamparter, Johannes Berg,
Aaro Koskinen, Andreas Kemnade, Kevin Hilman, Roger Quadros,
Tony Lindgren, Thomas Bogendoerfer, John Paul Adrian Glaubitz,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
H. Peter Anvin, Linus Walleij, Bartosz Golaszewski,
Dmitry Torokhov, Lee Jones, Pavel Machek, Matti Vaittinen,
Florian Fainelli, Jonas Gorski, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
linux-wireless, linux-omap, linux-arm-kernel, linux-mips,
linux-sh, linux-input, linux-leds, netdev, Bartosz Golaszewski
In-Reply-To: <20260520183815.2510387-1-arnd@kernel.org>
From: Arnd Bergmann <arnd@arndb.de>
The MIPS bcm53xx platform still uses the legacy gpiolib interfaces based
on gpio numbers, but other platforms do not.
Hide these interfaces inside of the existing #ifdef block and use the
modern interfaces in the common parts of the driver to allow building
it when the gpio_set_value() is left out of the kernel.
Reviewed-by: Jonas Gorski <jonas.gorski@gmail.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
drivers/net/dsa/b53/b53_common.c | 17 +++++------------
drivers/net/dsa/b53/b53_priv.h | 25 +++++++++++++++++++------
2 files changed, 24 insertions(+), 18 deletions(-)
diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index 2c4131ed7e30..d838511ae674 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -19,7 +19,7 @@
#include <linux/delay.h>
#include <linux/export.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
#include <linux/kernel.h>
#include <linux/math.h>
#include <linux/minmax.h>
@@ -965,17 +965,17 @@ EXPORT_SYMBOL(b53_configure_vlan);
static void b53_switch_reset_gpio(struct b53_device *dev)
{
- int gpio = dev->reset_gpio;
+ struct gpio_desc *gpio = dev->reset_gpio;
- if (gpio < 0)
+ if (IS_ERR(gpio))
return;
/* Reset sequence: RESET low(50ms)->high(20ms)
*/
- gpio_set_value(gpio, 0);
+ gpiod_set_value(gpio, 0);
mdelay(50);
- gpio_set_value(gpio, 1);
+ gpiod_set_value(gpio, 1);
mdelay(20);
dev->current_page = 0xff;
@@ -3092,7 +3092,6 @@ static int b53_switch_init(struct b53_device *dev)
{
u32 chip_id = dev->chip_id;
unsigned int i;
- int ret;
if (is63xx(dev))
chip_id = BCM63XX_DEVICE_ID;
@@ -3173,12 +3172,6 @@ static int b53_switch_init(struct b53_device *dev)
return -ENOMEM;
dev->reset_gpio = b53_switch_get_reset_gpio(dev);
- if (dev->reset_gpio >= 0) {
- ret = devm_gpio_request_one(dev->dev, dev->reset_gpio,
- GPIOF_OUT_INIT_HIGH, "robo_reset");
- if (ret)
- return ret;
- }
return 0;
}
diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h
index bd6849e5bb93..cd27a7344e89 100644
--- a/drivers/net/dsa/b53/b53_priv.h
+++ b/drivers/net/dsa/b53/b53_priv.h
@@ -148,7 +148,7 @@ struct b53_device {
u8 duplex_reg;
u8 jumbo_pm_reg;
u8 jumbo_size_reg;
- int reset_gpio;
+ struct gpio_desc *reset_gpio;
u8 num_arl_bins;
u16 num_arl_buckets;
enum dsa_tag_protocol tag_protocol;
@@ -467,23 +467,36 @@ static inline void b53_arl_search_read(struct b53_device *dev, u8 idx,
#ifdef CONFIG_BCM47XX
#include <linux/bcm47xx_nvram.h>
+#include <linux/gpio.h>
#include <bcm47xx_board.h>
-static inline int b53_switch_get_reset_gpio(struct b53_device *dev)
+static inline struct gpio_desc *b53_switch_get_reset_gpio(struct b53_device *dev)
{
enum bcm47xx_board board = bcm47xx_board_get();
+ int gpio, ret;
switch (board) {
case BCM47XX_BOARD_LINKSYS_WRT300NV11:
case BCM47XX_BOARD_LINKSYS_WRT310NV1:
- return 8;
+ gpio = 8;
+ break;
default:
- return bcm47xx_nvram_gpio_pin("robo_reset");
+ gpio = bcm47xx_nvram_gpio_pin("robo_reset");
}
+
+ if (!gpio_is_valid(gpio))
+ return ERR_PTR(-EINVAL);
+
+ ret = devm_gpio_request_one(dev->dev, gpio,
+ GPIOF_OUT_INIT_HIGH, "robo_reset");
+ if (ret)
+ return ERR_PTR(ret);
+
+ return gpio_to_desc(gpio);
}
#else
-static inline int b53_switch_get_reset_gpio(struct b53_device *dev)
+static inline struct gpio_desc *b53_switch_get_reset_gpio(struct b53_device *dev)
{
- return -ENOENT;
+ return ERR_PTR(-ENODEV);
}
#endif
--
2.39.5
^ permalink raw reply related
* [PATCH v2 00/10] gpiolib: fence off legacy interfaces
From: Arnd Bergmann @ 2026-05-20 18:38 UTC (permalink / raw)
To: linux-gpio
Cc: linux-kernel, Arnd Bergmann, Christian Lamparter, Johannes Berg,
Aaro Koskinen, Andreas Kemnade, Kevin Hilman, Roger Quadros,
Tony Lindgren, Thomas Bogendoerfer, John Paul Adrian Glaubitz,
Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
H. Peter Anvin, Linus Walleij, Bartosz Golaszewski,
Dmitry Torokhov, Lee Jones, Pavel Machek, Matti Vaittinen,
Florian Fainelli, Jonas Gorski, Andrew Lunn, Vladimir Oltean,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
linux-wireless, linux-omap, linux-arm-kernel, linux-mips,
linux-sh, linux-input, linux-leds, netdev
From: Arnd Bergmann <arnd@arndb.de>
This is an update of all the patches that are still required before
we can actually turn off CONFIG_GPIOLIB_LEGACY for most platforms
in the final patch of this series.
I originally posted this as a series in
https://lore.kernel.org/all/20250808151822.536879-1-arnd@kernel.org/
I added more patches for the p54spi driver that I had originally
sent separately and submitted the remaining ones separately to
the subsystem maintainers, with about two thirds getting picked
up so far.
If possible, please apply the patches to the respective
architecture (mips, sh, x86, soc/omap) or subsystem
(wireless, net-next, led, input) trees.
Arnd
Arnd Bergmann (10):
[v2] [net-next] net: dsa: b53: hide legacy gpiolib usage on non-mips
[v3] input: gpio-keys: make legacy gpiolib optional
[v2] x86/olpc: select GPIOLIB_LEGACY
[v2] sh: select legacy gpiolib interface
[v2] mips: select legacy gpiolib interfaces where used
[v4] leds: gpio: make legacy gpiolib interface optional
[v6 net-next] dt-bindings: net: add st,stlc4560/p54spi binding
[v6 net-next] p54spi: convert to devicetree
[v6 omap] ARM: dts: omap2: add stlc4560 spi-wireless node
gpiolib: turn off legacy interface by default
Cc: Christian Lamparter <chunkeey@googlemail.com>
Cc: Johannes Berg <johannes@sipsolutions.net>
Cc: Aaro Koskinen <aaro.koskinen@iki.fi>
Cc: Andreas Kemnade <andreas@kemnade.info>
Cc: Kevin Hilman <khilman@baylibre.com>
Cc: Roger Quadros <rogerq@kernel.org>
Cc: Tony Lindgren <tony@atomide.com>
Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
Cc: Thomas Gleixner <tglx@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: x86@kernel.org
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: Linus Walleij <linusw@kernel.org>
Cc: Bartosz Golaszewski <brgl@kernel.org>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Lee Jones <lee@kernel.org>
Cc: Pavel Machek <pavel@kernel.org>
Cc: Matti Vaittinen <mazziesaccount@gmail.com>
Cc: Florian Fainelli <florian.fainelli@broadcom.com>
Cc: Jonas Gorski <jonas.gorski@gmail.com>
Cc: Andrew Lunn <andrew@lunn.ch>
Cc: Vladimir Oltean <olteanv@gmail.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: linux-wireless@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-omap@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-mips@vger.kernel.org
Cc: linux-sh@vger.kernel.org
Cc: linux-gpio@vger.kernel.org
Cc: linux-input@vger.kernel.org
Cc: linux-leds@vger.kernel.org
Cc: netdev@vger.kernel.org
.../bindings/net/wireless/st,stlc4560.yaml | 61 +++++++++++++++++
MAINTAINERS | 1 +
arch/arm/boot/dts/ti/omap/omap2.dtsi | 4 ++
.../dts/ti/omap/omap2420-n8x0-common.dtsi | 12 ++++
arch/arm/mach-omap2/board-n8x0.c | 18 -----
arch/mips/Kconfig | 5 ++
arch/mips/alchemy/Kconfig | 1 -
arch/mips/txx9/Kconfig | 1 +
arch/sh/Kconfig | 1 +
arch/sh/boards/Kconfig | 8 +++
arch/sh/boards/mach-highlander/Kconfig | 1 +
arch/sh/boards/mach-rsk/Kconfig | 3 +
arch/x86/Kconfig | 1 +
drivers/gpio/Kconfig | 9 ++-
drivers/input/keyboard/gpio_keys.c | 7 +-
drivers/input/keyboard/gpio_keys_polled.c | 2 +
drivers/leds/leds-gpio.c | 51 +++++++++-----
drivers/mfd/rohm-bd71828.c | 1 -
drivers/mfd/rohm-bd718x7.c | 1 -
drivers/net/dsa/b53/b53_common.c | 17 ++---
drivers/net/dsa/b53/b53_priv.h | 25 +++++--
drivers/net/wireless/intersil/p54/p54spi.c | 67 +++++++------------
drivers/net/wireless/intersil/p54/p54spi.h | 3 +
include/linux/gpio_keys.h | 2 +
include/linux/leds.h | 2 +
sound/pci/Kconfig | 1 +
26 files changed, 201 insertions(+), 104 deletions(-)
create mode 100644 Documentation/devicetree/bindings/net/wireless/st,stlc4560.yaml
--
2.39.5
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox