From nobody Tue Feb 10 21:59:31 2026 Received: from mail-wm1-f51.google.com (mail-wm1-f51.google.com [209.85.128.51]) (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 331E82F3607 for ; Mon, 3 Nov 2025 09:35:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762162558; cv=none; b=Ic5dIxs3FCaQuvPnJySYd8oYCIq4T2+/51ZPiAlDAooiI6vyhyQ71SpPK1tNCUpB35jXuoZLQZ0Xhw31ehPkWs952EM+AXVmQxCLYFtSQn0uKNMdHHOSwPsWnDqpnh08/LFdxHfLJIiFc1/tTnZbfUV7xdPiwpsWoCB+XmNqvpE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1762162558; c=relaxed/simple; bh=LVirDKugKBwbbhccPkhESHv27V21xLYG8l1u0h8U634=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=BNbzYqQzOLJt4AuLvAIRwKdEmm6IvQ3OHiGq1JzIiJ7KG+G2t3LtF/w0PbLWwldhXTZvX+2Ye2on5sNMwgkIb4g+lhfKsw7arA0wPaedWDU0TZ7RKACdiCRSCD2bZYZiNz/Ly8kXCZmkADn7+CcAkVe2opd1xKCpnEe/7HvLFSE= 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=WbyEUyYH; arc=none smtp.client-ip=209.85.128.51 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="WbyEUyYH" Received: by mail-wm1-f51.google.com with SMTP id 5b1f17b1804b1-475dc6029b6so37197395e9.0 for ; Mon, 03 Nov 2025 01:35:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1762162554; x=1762767354; 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=Ccx+aLo9kBZlyDoxwdiUlxqcXIUYEmsoX9N+IulSngU=; b=WbyEUyYHMKr84mMD70rTZjLf3j6Lh6q35Gh/9YxOdly6LhgPDOAuJ+X0K8t1VkgvNX taduIJ3t8ujN/ZPD90NWCMqKI2WPnVUFF8am9GyJQpozlGFkwAUrxGzl3ubdmvRDWKRF U4SLxZeyws8LUZ48aAghIVvjAAVG89GNjT+K49RP/d538SYoOhlcChG0oEio7sxuHono 8DY1rfF6PWWj5yMZhUpviXlOJSIctORwrf0TgPRxAnZqsEc2Am64Kfw7ddhKqNfsnpAd PZnXv/BHXp2SfGlFdN9pyShL/1FExajUFve/2GfQV5+sr+3SNnepQ8bdnUuT5AAWbQYg uGuw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1762162554; x=1762767354; 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=Ccx+aLo9kBZlyDoxwdiUlxqcXIUYEmsoX9N+IulSngU=; b=uUSsx+jffNL4p73ht8WsW3XNHApC7r4d6TSG2ECCvxdGJg80Htwv9EfF107CPziT1V 4a8LP0KEAaxvadqTlX5eSkwJQkDV1S+C4uCD2nyyl867G/BTCPWUovpbHhZbw4rfPkE1 h/vYFU1uaU4vHwZT2CA1U4AZleXIWAAN1QErQlyRfiCllyqlkdJXvpo9NnlWa0MgXoxx QWdqh/Gsr/fXYYx1Jkp+nWEIoaHmYJXB13Qi4KvMo4s5OZfY0eupE9YQ2txyXjU5dcfA wU3BLV1vwUGF9kaWCEg5o7rPQHUm/S7Cz3vmd5c71Vcm/ezylahzTlbw9SoCZh85p1/S 1l5w== X-Forwarded-Encrypted: i=1; AJvYcCXIaccOhZA1pmJ/U/sTk1lCseRtvXwUFIclyIuQu7DAM1hj0gLY4qYr0tiocRiWGlYiaQ94xffFMJZZ0So=@vger.kernel.org X-Gm-Message-State: AOJu0YwMyoWJMwWYBB3uctsGHc+ctHJxNmE4hdqw1YHSCB2pkQriNEn7 H9DYcxZQ9weQ8Q7XzNrx73oU5vxrkKDn5ywVaVxhA46Vq71CrEzCqZdWV3mg/GP09WI= X-Gm-Gg: ASbGnctJi4kIGLz7Qqm1nVkQfvMT5HdWNUGp8UWBLNi/odv2V7OQ8iz++ms2GtmNEQA uRYiqdIKTa4O4uLKOYLleGMtOIxiqJ4OF7ncRUCFww1Kr4YkTyhXsxZoGxFtsH8n/3nK9xR8KDO 2SIMlHQZlyef6CetH4n7qFzToCxUFd2Fq1zJA0zF7drCd9A8vVW8uy4vifWLLTCAf4UA22pi9L4 Brn47uXPMUf9YdhHB6xuWP2PZuuxTlnJUpBZ4Kz9Vm1aNtnQZP1p6Mn0HNiHQ6vkUUzUluiVNmI IFY5Tez8CJQnupP0EKHx6Jhmmh/JJ1AKTU1d00ZRant67JV7VFTNzR2cjYttq+LqtLqURE8RG1X OHcU+BgYgyMdYV1VK6tNiKIffAmISgiA9Q8YBR7LkGLQxAhqStE6LH3PVc6pkRBJSL+K9bVMIe2 2OuSpW X-Google-Smtp-Source: AGHT+IG+c9TBxrNO8Rhcga0cjbgIHbzYpexTcWraDC03lZYlbHD8b28uw8YTYq3tgyvQ6c0CGDmtaQ== X-Received: by 2002:a05:600c:3e07:b0:471:a96:d1b6 with SMTP id 5b1f17b1804b1-4773b1f9db7mr85016295e9.7.1762162554470; Mon, 03 Nov 2025 01:35:54 -0800 (PST) Received: from [127.0.1.1] ([2a01:cb1d:dc:7e00:e6eb:2a19:143f:b127]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4773c4ac5d6sm147285675e9.8.2025.11.03.01.35.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 03 Nov 2025 01:35:53 -0800 (PST) From: Bartosz Golaszewski Date: Mon, 03 Nov 2025 10:35:30 +0100 Subject: [PATCH v4 10/10] 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: <20251103-reset-gpios-swnodes-v4-10-6461800b6775@linaro.org> References: <20251103-reset-gpios-swnodes-v4-0-6461800b6775@linaro.org> In-Reply-To: <20251103-reset-gpios-swnodes-v4-0-6461800b6775@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=7164; i=bartosz.golaszewski@linaro.org; h=from:subject:message-id; bh=zGQChOLYdShQxCyhFrgghwt6h1bOoSffKyYTaLJagTw=; b=owEBbQKS/ZANAwAKARGnLqAUcddyAcsmYgBpCHdmkfkiw+TPahVB/J5Ozb3L+OfwnbkEAaAM8 jTvH0EnPOmJAjMEAAEKAB0WIQQWnetsC8PEYBPSx58Rpy6gFHHXcgUCaQh3ZgAKCRARpy6gFHHX ct08EACxza1Nitcc8hYrFjP4g8/IEkDBsLvHarp0JA2folddmog9HvZ+5ikQyAfCGA0QNJPGcwh wO3i/Qoe7yClroNovCJpbq4u5qhaXhhy7L9uvYekvU7ythdhwPP7mquZhP2oxBLXKgi6WdFmDTy O0Ag+0NMjhGHRCGnGASBJJ+LIhS2Ub9KwLxWQ1NznREdIMvSCRPNRkc3BUTLS4WvCipGf6OozKZ h9lK5HPErNsanQ55jm9twkdV7VPIU5mUBUFiSmLcbZTsYDTGQPZxDeq9ryizMtY1mlHnBBgWqsy DudImTzWMoEjPg/Cr+ovz07GFjG5hqIF0HSoHU0pXW+BJ1WTfZV9uAHWmlWsdQM4Xw6v3+cfrMu n7OisPGEys+O380l+82SLvRU3rbBXm2yeSvlmOrpA6vDXrL44wSLXwWAn62zR6qgquNmkA9Il+B yaEpBjODGUFTWd2Sb8fYz60lzzKT0IpWfyw0VfCW7WyNJpHzjdLuYcQdOrCKQBevz87KfRCPBYP fBZZbKva6K1RO6MN8xgeA+AkQYpfIc4n7yPdjaw+XQXVisYS1DE4TIZMvIfB+qwmsZJe2dAgH4Z aah7PYXttCW5fv7QERqORVou/+Y8g9Vm+H1kczeVtjhFV509pxETDA+Sua3tYkV+o/tJ7b7+RNg uRGLDCgqYkxB/Sw== 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 | 132 ++++++++++++++++++++++++++++++-----------------= ---- 1 file changed, 78 insertions(+), 54 deletions(-) diff --git a/drivers/reset/core.c b/drivers/reset/core.c index fcf1c24086e565015b0956fdd40334274a1edb00..770d82ed7978f1006882908d925= 26fc6d8be3299 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,13 @@ 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_FWNODE("reset-gpios", + parent->fwnode, + offset, lflags); + id =3D ida_alloc(&reset_gpio_ida, GFP_KERNEL); if (id < 0) return id; @@ -920,11 +942,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 +949,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