From nobody Fri Dec 19 14:22:23 2025 Received: from mail-wr1-f49.google.com (mail-wr1-f49.google.com [209.85.221.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 86CE92E2679 for ; Wed, 5 Nov 2025 08:48:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762332494; cv=none; b=e7hn56zL8P5xAxe6RfXwbf61/MMOS+k0PVXHyre4edZlmxdHg+60h0U2kiP9F5H3Td3FmlNJTx0XNVZWjNNuj7ET6HsoxYKKmWLnCNhuGPk/ZqHgw1orkQ+r/5lJBI+VkmO1ZGjgQSU6o4nfOEIAeYn6uQkz3F8N2d2XedPbPxU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762332494; c=relaxed/simple; bh=SGEipYyBFPCCyVC6q8YgOSs4LCXD3vaIIQV9W9NaxB4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=toBr7/eA8iiE+I7LROV9gcK/eTimoB7+6hJCULTMxjpXfCY1X9ymvYizGpSrlmQmkUymhE3dDbQBXSyv51RL+oQNfauflCTC9UWam/Ba6SZjPYxZ64q0n/0KsKLoJbBciPFRJlJazXHqhya4eiKxgfGi4/U3DQPgoltt3JgpOFc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl; spf=none smtp.mailfrom=bgdev.pl; dkim=pass (2048-bit key) header.d=bgdev-pl.20230601.gappssmtp.com header.i=@bgdev-pl.20230601.gappssmtp.com header.b=qtO7Sb8g; arc=none smtp.client-ip=209.85.221.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bgdev.pl Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=bgdev.pl Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bgdev-pl.20230601.gappssmtp.com header.i=@bgdev-pl.20230601.gappssmtp.com header.b="qtO7Sb8g" Received: by mail-wr1-f49.google.com with SMTP id ffacd0b85a97d-3ece1102998so4387135f8f.2 for ; Wed, 05 Nov 2025 00:48:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1762332491; x=1762937291; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=DkhhDNpmKZjGJKpspl88pg7px7XG43dcD6b9QvYDK5U=; b=qtO7Sb8gg3JwQxi9AazobilbIhGG9+btvldMINwfkCRsQN2X4ODwsFY16FnjQSSIms kPyoOXE4GgYEvU61UrKdnNrIUCKRFn1nZCc6h4yQdXYHkpvR6RHiR+shmNVntOGydRK1 06Eboa3SJ418r1JauJYYI5azGLhvd4c45n6jrkQ7Afqio3s9NgYOsFztIh+BoqYPULzu ZcwTGJGhvcAmeqiB5mYDSd52e/3qPtPbJG5cSkaM0tobtE80hlxMVb0Psw+MQAv3Sgqq Nqqa7IFUHNdpLXVPuiRdwdWEM1ECegivBZ2tcDv1WGVmmK5vVS2y1j/6PU8VD+39q/Ps eXTA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762332491; x=1762937291; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=DkhhDNpmKZjGJKpspl88pg7px7XG43dcD6b9QvYDK5U=; b=rsfVgarZxqrftqv7KBhyxVfUkwOis23EH10zoyHNLZs395aB7xPdFhQpWv3YdJB4wB nH/6JwOyLrovNe/eRGT3ASd4UWTMUAwc0fVcUJ8ozT7/NlXdzSAmzGj1dYbW9iqTNvZp rLYSCg+UhnbNiKEm6pEprqbWJjvqmJT/dsq2FgHdT9Drz5KyqCa/GU1L6Bl6NFlkBvfq ogXpOLM9D9eFzN1mWDrRztb+uBN4jy1vmqq3BXko4NnwEiNtU6puFQRKEcGrYniMLCdx NtG04G8dyhYeGIyNlXdiLihMH/XCPB7CtymhiBxG/GQet47++93HxNWbgMH4BB5zJcNq T1Dw== X-Forwarded-Encrypted: i=1; AJvYcCXdTDsk2wL9mBFwsz2z1P82XBb51+9jnA4iy9esdqnZ4bLEXHZC9YjdhMeipvJLLYCg1Uyfvuik6OoUSUQ=@vger.kernel.org X-Gm-Message-State: AOJu0Yyu+OGmz/dAFs9SUooPGeoPnYbnr3f5auZ+wtF9MlTeM5PFeNDC P9ddzGFZqOC1AUqZa5pDGveflXWGZzcfthxKxNCKAWSTkFotLoj588+9qHWNxxV+YzEIAL6Bl87 W4gkPoebdYw== X-Gm-Gg: ASbGncuyMtgL6NyPpvu3bhhl78TrCT5xPALKJsUvVkgtN2VOtmCL90r1KJioVvp66e6 VgUZXIa6fYCDKXd7rO25hDygL2TUUuolosLPpO2sSZL3X4Ap07ltCo/D4cyLYMRQL1Y8kfk/x+n BOx0xH/CkM2PKxZw1GIFazqXws5540qNuFocIVjriAd3u80AJ8jqbX/ns0VWvzt8PsgWmNHQpFR iGMzQ1fpL2cOsnC4qnxKhIBw6BLNdwDBCS3E8faSh/zoLlPvqNp/6bKTSpA19lJmzTf3q9eKP0t wsnZB0aTOaQxkKxsU6l2LH9eboA9WPg7x7xTSpQLzmu5k+uzBZHvIU+6W/s2uLohINEJEYLtM1/ IFALHAKpwNlxZM9/udy10NS0FkfKgXDp9VsLL0ebOsHcTxPNYxTzGK9EN1cseG0WqKcphow== X-Google-Smtp-Source: AGHT+IGTUfxyJN5QHNOp0FTOnoLQgzs14kVKOEtC+nMrHYH+LcVaxtpywpF6tGJ9j4zAjwjvArwqFw== X-Received: by 2002:a05:6000:458f:b0:429:cbba:b242 with SMTP id ffacd0b85a97d-429e3306470mr1523705f8f.41.1762332490686; Wed, 05 Nov 2025 00:48:10 -0800 (PST) Received: from [127.0.1.1] ([2a01:cb1d:dc:7e00:4e71:8371:5a52:77e4]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-429dc1f9cdbsm9315936f8f.34.2025.11.05.00.48.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Nov 2025 00:48:09 -0800 (PST) From: Bartosz Golaszewski Date: Wed, 05 Nov 2025 09:47:39 +0100 Subject: [PATCH v5 8/8] reset: gpio: use software nodes to setup the GPIO lookup Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20251105-reset-gpios-swnodes-v5-8-1f67499a8287@linaro.org> References: <20251105-reset-gpios-swnodes-v5-0-1f67499a8287@linaro.org> In-Reply-To: <20251105-reset-gpios-swnodes-v5-0-1f67499a8287@linaro.org> To: Linus Walleij , Bartosz Golaszewski , Andy Shevchenko , Daniel Scally , Heikki Krogerus , Sakari Ailus , Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , Philipp Zabel , Krzysztof Kozlowski Cc: linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, Bartosz Golaszewski X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=7132; i=bartosz.golaszewski@linaro.org; h=from:subject:message-id; bh=NNQdvThjugcgWNXPcBcBS6gI52byrFAWIB9wM4h8qXg=; b=owEBbQKS/ZANAwAKARGnLqAUcddyAcsmYgBpCw8yu1+tDlfSt4WuUulr+TLFSJdB3g8qziixY B74F11UPXuJAjMEAAEKAB0WIQQWnetsC8PEYBPSx58Rpy6gFHHXcgUCaQsPMgAKCRARpy6gFHHX cr1ND/9zeaDEMfSGJ6sFnCXa81JnjVuhcR/lMtxHf4udsqyjNAXIcSXpxXHKffLYaG8Fr39Xxd1 EydW+kJbY6qoaZDS5iXNm8aXsZl990kvC1or3OWfVvL226s3ZUOXL/Dmagok6Yo6VdYj54gMuOd /I0Fy45FfGNXMn4CJZczIWZC8qFYa398RWzQdmYxTIiSeJiLjBbCbboFqWKzOBAmVvTg5wF40Pu 3vCU2pBUT5DVJoh7HHYiB5BJ59axl4ycnXbf97Q+03sNPXakO7mKAIgCsxUrl7HBCuZt/TpiQiT B0dqiIbzIs+kwk4hvDuhvgFkSc64bGxpA+CvWctGtLLAZG2lmm3tTSZjjGk/NOzCdiK6taFXQHh 9VtL6y18Fnv97p8M1Q15bWZB3jKe5f5ERhlRI0pbpI5Ia4guNu3a+Tw9wtfXQpwqAuOJViy5qXl 7S+4VMLHJbsHTfrjP9Fbic++ocS83Bu5ZIUNd3M4KjlpQB0RSfGGepSiR5Ooq9izM8s3gciyBE9 h+KXawiFy4us4GwQ7CJ+3Nabw+VxjUC/4v+mjlRRVj5bth1J73Y7opJ46yFsReWYXYWyoe8l2FO 7hjwcPqI2m0M0B5FrqWDVhz+DqUHyCCnAxgztV/ffn+2wjevtkFt0pUcCpxYanR7j8lgyAlx+ov yWEQj8EO+3TUSHA== X-Developer-Key: i=bartosz.golaszewski@linaro.org; a=openpgp; fpr=169DEB6C0BC3C46013D2C79F11A72EA01471D772 From: Bartosz Golaszewski GPIO machine lookup is a nice mechanism for associating GPIOs with consumers if we don't know what kind of device the GPIO provider is or when it will become available. However in the case of the reset-gpio, we are already holding a reference to the device and so can reference its firmware node. Let's setup a software node that references the relevant GPIO and attach it to the auxiliary device we're creating. Reviewed-by: Philipp Zabel Acked-by: Linus Walleij Signed-off-by: Bartosz Golaszewski --- drivers/reset/core.c | 129 ++++++++++++++++++++++++++++++-----------------= ---- 1 file changed, 75 insertions(+), 54 deletions(-) diff --git a/drivers/reset/core.c b/drivers/reset/core.c index fcf1c24086e565015b0956fdd40334274a1edb00..66a99bdfb7093232d169c92d49c= b953c4b1033e6 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -77,10 +78,12 @@ struct reset_control_array { /** * struct reset_gpio_lookup - lookup key for ad-hoc created reset-gpio dev= ices * @of_args: phandle to the reset controller with all the args like GPIO n= umber + * @swnode: Software node containing the reference to the GPIO provider * @list: list entry for the reset_gpio_lookup_list */ struct reset_gpio_lookup { struct of_phandle_args of_args; + struct fwnode_handle *swnode; struct list_head list; }; =20 @@ -822,52 +825,45 @@ static void __reset_control_put_internal(struct reset= _control *rstc) kref_put(&rstc->refcnt, __reset_control_release); } =20 -static int __reset_add_reset_gpio_lookup(struct gpio_device *gdev, int id, - struct device_node *np, - unsigned int gpio, - unsigned int of_flags) +static void reset_gpio_aux_device_release(struct device *dev) { - unsigned int lookup_flags; - const char *label_tmp; + struct auxiliary_device *adev =3D to_auxiliary_dev(dev); =20 - /* - * Later we map GPIO flags between OF and Linux, however not all - * constants from include/dt-bindings/gpio/gpio.h and - * include/linux/gpio/machine.h match each other. - */ - if (of_flags > GPIO_ACTIVE_LOW) { - pr_err("reset-gpio code does not support GPIO flags %u for GPIO %u\n", - of_flags, gpio); - return -EINVAL; + kfree(adev); +} + +static int reset_add_gpio_aux_device(struct device *parent, + struct fwnode_handle *swnode, + int id, void *pdata) +{ + struct auxiliary_device *adev; + int ret; + + adev =3D kzalloc(sizeof(*adev), GFP_KERNEL); + if (!adev) + return -ENOMEM; + + adev->id =3D id; + adev->name =3D "gpio"; + adev->dev.parent =3D parent; + adev->dev.platform_data =3D pdata; + adev->dev.release =3D reset_gpio_aux_device_release; + device_set_node(&adev->dev, swnode); + + ret =3D auxiliary_device_init(adev); + if (ret) { + kfree(adev); + return ret; } =20 - label_tmp =3D gpio_device_get_label(gdev); - if (!label_tmp) - return -EINVAL; + ret =3D __auxiliary_device_add(adev, "reset"); + if (ret) { + auxiliary_device_uninit(adev); + kfree(adev); + return ret; + } =20 - char *label __free(kfree) =3D kstrdup(label_tmp, GFP_KERNEL); - if (!label) - return -ENOMEM; - - /* Size: one lookup entry plus sentinel */ - struct gpiod_lookup_table *lookup __free(kfree) =3D kzalloc(struct_size(l= ookup, table, 2), - GFP_KERNEL); - if (!lookup) - return -ENOMEM; - - lookup->dev_id =3D kasprintf(GFP_KERNEL, "reset.gpio.%d", id); - if (!lookup->dev_id) - return -ENOMEM; - - lookup_flags =3D GPIO_PERSISTENT; - lookup_flags |=3D of_flags & GPIO_ACTIVE_LOW; - lookup->table[0] =3D GPIO_LOOKUP(no_free_ptr(label), gpio, "reset", - lookup_flags); - - /* Not freed on success, because it is persisent subsystem data. */ - gpiod_add_lookup_table(no_free_ptr(lookup)); - - return 0; + return ret; } =20 /* @@ -875,9 +871,11 @@ static int __reset_add_reset_gpio_lookup(struct gpio_d= evice *gdev, int id, */ static int __reset_add_reset_gpio_device(const struct of_phandle_args *arg= s) { + struct property_entry properties[] =3D { {}, {} }; struct reset_gpio_lookup *rgpio_dev; - struct auxiliary_device *adev; - int id, ret; + unsigned int offset, of_flags; + struct device *parent; + int id, ret, lflags; =20 /* * Currently only #gpio-cells=3D2 is supported with the meaning of: @@ -895,6 +893,23 @@ static int __reset_add_reset_gpio_device(const struct = of_phandle_args *args) */ lockdep_assert_not_held(&reset_list_mutex); =20 + offset =3D args->args[0]; + of_flags =3D args->args[1]; + + /* + * Later we map GPIO flags between OF and Linux, however not all + * constants from include/dt-bindings/gpio/gpio.h and + * include/linux/gpio/machine.h match each other. + * + * FIXME: Find a better way of translating OF flags to GPIO lookup + * flags. + */ + if (of_flags > GPIO_ACTIVE_LOW) { + pr_err("reset-gpio code does not support GPIO flags %u for GPIO %u\n", + of_flags, offset); + return -EINVAL; + } + struct gpio_device *gdev __free(gpio_device_put) =3D gpio_device_find_by_fwnode(of_fwnode_handle(args->np)); if (!gdev) @@ -909,6 +924,10 @@ static int __reset_add_reset_gpio_device(const struct = of_phandle_args *args) } } =20 + lflags =3D GPIO_PERSISTENT | (of_flags & GPIO_ACTIVE_LOW); + parent =3D gpio_device_to_device(gdev); + properties[0] =3D PROPERTY_ENTRY_GPIO("reset-gpios", parent->fwnode, offs= et, lflags); + id =3D ida_alloc(&reset_gpio_ida, GFP_KERNEL); if (id < 0) return id; @@ -920,11 +939,6 @@ static int __reset_add_reset_gpio_device(const struct = of_phandle_args *args) goto err_ida_free; } =20 - ret =3D __reset_add_reset_gpio_lookup(gdev, id, args->np, args->args[0], - args->args[1]); - if (ret < 0) - goto err_kfree; - rgpio_dev->of_args =3D *args; /* * We keep the device_node reference, but of_args.np is put at the end @@ -932,19 +946,26 @@ static int __reset_add_reset_gpio_device(const struct= of_phandle_args *args) * Hold reference as long as rgpio_dev memory is valid. */ of_node_get(rgpio_dev->of_args.np); - adev =3D auxiliary_device_create(gpio_device_to_device(gdev), "reset", - "gpio", &rgpio_dev->of_args, id); - ret =3D PTR_ERR_OR_ZERO(adev); + + rgpio_dev->swnode =3D fwnode_create_software_node(properties, NULL); + if (IS_ERR(rgpio_dev->swnode)) { + ret =3D PTR_ERR(rgpio_dev->swnode); + goto err_put_of_node; + } + + ret =3D reset_add_gpio_aux_device(parent, rgpio_dev->swnode, id, + &rgpio_dev->of_args); if (ret) - goto err_put; + goto err_del_swnode; =20 list_add(&rgpio_dev->list, &reset_gpio_lookup_list); =20 return 0; =20 -err_put: +err_del_swnode: + fwnode_remove_software_node(rgpio_dev->swnode); +err_put_of_node: of_node_put(rgpio_dev->of_args.np); -err_kfree: kfree(rgpio_dev); err_ida_free: ida_free(&reset_gpio_ida, id); --=20 2.51.0