From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B62AC3BE165; Sat, 17 Oct 2026 16:44:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792255489; cv=none; b=EmafvYjGdhxrRtW5dBXAQviwlo4lG3S+Z9wpaqph4pWr4Dkgy4RtfqAb6IzFw5QdRJeLbYrmqsTcVY+MJuoIqOpSZMpDL+5aeKlZDBn6zeeJtPm8F+lZE07rNWxhYxngm/J6qHRTXlIksguXAvWIFoOczz2Qhc79fUbSqdT/3Ww= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792255489; c=relaxed/simple; bh=dd4Smb96op+ZZvUPxX3ilOlsdjSdkgLjMfAFSwhTHIs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=m8gny9UH1hYKw4+6ADeKgtLI3kPJHAJC8LhBH+zpyyyuL16SOPMUss01/R0OOZNgfqpU/TYWSgwOjP1jqp4qd6/Ak13nuBUw05OQ8buWqcQWBpCWS8AYrMvOhTuyJ/uT37/GtPmpD0YYb9LMoiLzEtZceweMMLOCEFeeislkgOc= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=EwpajsNG; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="EwpajsNG" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0E78D1F000C4; Sat, 17 Oct 2026 16:44:47 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1792255488; bh=b3esC9n3ri/DFEYIy1Rou3YND0xlLIPIjNmogszAm/k=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=EwpajsNGe+sZEC2R5AZP7FrYs4Itz8vUv/dynyKaZQs1RodUvmv65dOuLprppmABz JK8c9ypVMyMa7LYuc7Os2r0o2pVxvRXHsVZbbmhFlXF/iF6V7bDSsB8zRpi4kORT94 7xpGydlPuBbgXspB9FPVcVW0PRMpHC0cWM7RIdNI= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Linus Walleij , =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= , Bartosz Golaszewski , Sasha Levin Subject: [PATCH 6.12 751/869] gpiolib: introduce gpio_chip setters that return values Date: Sat, 17 Oct 2026 17:59:52 +0200 Message-ID: <20261017160056.189883681@linuxfoundation.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261017160036.979869304@linuxfoundation.org> References: <20261017160036.979869304@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: patches@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 6.12-stable review patch. If anyone has any objections, please let me know. ------------------ From: Bartosz Golaszewski [ Upstream commit 98ce1eb1fd87ea1b016e0913ef6836ab0139b5c4 ] Add new variants of the set() and set_multiple() callbacks that have integer return values allowing to indicate failures to users of the GPIO consumer API. Until we convert all GPIO providers treewide to using them, they will live in parallel to the existing ones. Make sure that providers cannot define both. Prefer the new ones and only use the old ones as fallback. Reviewed-by: Linus Walleij Acked-by: Uwe Kleine-König Link: https://lore.kernel.org/r/20250220-gpio-set-retval-v2-5-bc4cfd38dae3@linaro.org Signed-off-by: Bartosz Golaszewski Stable-dep-of: c87c9046c4e0 ("pinctrl: mediatek: paris: bypass pinctrl GPIO layer in set GPIO direction") Signed-off-by: Sasha Levin --- drivers/gpio/gpiolib.c | 28 ++++++++++++++++++++++++++-- drivers/leds/leds-aw200xx.c | 2 +- include/linux/gpio/driver.h | 10 ++++++++++ 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 5f23da5ef8c93..5f73f0c29cf6a 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -945,6 +945,11 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data, int base = 0; int ret; + /* Only allow one set() and one set_multiple(). */ + if ((gc->set && gc->set_rv) || + (gc->set_multiple && gc->set_multiple_rv)) + return -EINVAL; + gdev = kzalloc(sizeof(*gdev), GFP_KERNEL); if (!gdev) return -ENOMEM; @@ -2724,11 +2729,21 @@ EXPORT_SYMBOL_GPL(gpiod_direction_input); static int gpiochip_set(struct gpio_chip *gc, unsigned int offset, int value) { + int ret; + lockdep_assert_held(&gc->gpiodev->srcu); - if (WARN_ON(unlikely(!gc->set))) + if (WARN_ON(unlikely(!gc->set && !gc->set_rv))) return -EOPNOTSUPP; + if (gc->set_rv) { + ret = gc->set_rv(gc, offset, value); + if (ret > 0) + ret = -EBADE; + + return ret; + } + gc->set(gc, offset, value); return 0; } @@ -3426,9 +3441,18 @@ static int gpiochip_set_multiple(struct gpio_chip *gc, lockdep_assert_held(&gc->gpiodev->srcu); - if (WARN_ON(unlikely(!gc->set_multiple && !gc->set))) + if (WARN_ON(unlikely(!gc->set_multiple && !gc->set_multiple_rv && + !gc->set && !gc->set_rv))) return -EOPNOTSUPP; + if (gc->set_multiple_rv) { + ret = gc->set_multiple_rv(gc, mask, bits); + if (ret > 0) + ret = -EBADE; + + return ret; + } + if (gc->set_multiple) { gc->set_multiple(gc, mask, bits); return 0; diff --git a/drivers/leds/leds-aw200xx.c b/drivers/leds/leds-aw200xx.c index f9d9844e02738..7adf77c0a48a9 100644 --- a/drivers/leds/leds-aw200xx.c +++ b/drivers/leds/leds-aw200xx.c @@ -379,7 +379,7 @@ static void aw200xx_enable(const struct aw200xx *const chip) static void aw200xx_disable(const struct aw200xx *const chip) { - return gpiod_set_value_cansleep(chip->hwen, 0); + gpiod_set_value_cansleep(chip->hwen, 0); } static int aw200xx_probe_get_display_rows(struct device *dev, diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 2dd7cb9cc270a..ac42f0164d5f9 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -346,6 +346,10 @@ struct gpio_irq_chip { * stores them in "bits", returns 0 on success or negative error * @set: assigns output value for signal "offset" * @set_multiple: assigns output values for multiple signals defined by "mask" + * @set_rv: assigns output value for signal "offset", returns 0 on success or + * negative error value + * @set_multiple_rv: assigns output values for multiple signals defined by + * "mask", returns 0 on success or negative error value * @set_config: optional hook for all kinds of settings. Uses the same * packed config format as generic pinconf. * @to_irq: optional hook supporting non-static gpiod_to_irq() mappings; @@ -441,6 +445,12 @@ struct gpio_chip { void (*set_multiple)(struct gpio_chip *gc, unsigned long *mask, unsigned long *bits); + int (*set_rv)(struct gpio_chip *gc, + unsigned int offset, + int value); + int (*set_multiple_rv)(struct gpio_chip *gc, + unsigned long *mask, + unsigned long *bits); int (*set_config)(struct gpio_chip *gc, unsigned int offset, unsigned long config); -- 2.53.0