From nobody Tue Dec 2 02:27:52 2025 Received: from mail-wm1-f45.google.com (mail-wm1-f45.google.com [209.85.128.45]) (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 C3AF7239E76 for ; Thu, 20 Nov 2025 13:24:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763645072; cv=none; b=SnZNQBsAS5xH61G0Hf+40Kctn7Me4VuFOYqJkClDEL1h3MKC1cvf2HU9CYOlK+AbE0qI3uNY6G88SEN4vcvIX2R5HfnYJslFft2RZnF4KBU+f8U0t73NCMDQ6mmATteaMTYx0nKQeaQ6yDUfFeeU0+NOAAU++aXD2RYnAVQ0k9w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763645072; c=relaxed/simple; bh=aZ73W3YHGMU6xBUkukDk+WxhhQlc8F45xSk2D12rMD0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=NET6yVhQnE6Pm+0jT55HHEw88KysZBJ7c1L02XRwMQFWFBZw8cYlV+1ZNu7UUBD7w2RAJMvSfp6uD/XCRVxRwy2GIaj706xgwKr2/jVWa0bYkBqYXjMSp9dTYrRgpyJXxl657DnFHEIjh/JsO/u3aU/OHSDShmihlVxMCTUexY4= 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=0uYfHLY4; arc=none smtp.client-ip=209.85.128.45 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="0uYfHLY4" Received: by mail-wm1-f45.google.com with SMTP id 5b1f17b1804b1-47118259fd8so7367675e9.3 for ; Thu, 20 Nov 2025 05:24:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20230601.gappssmtp.com; s=20230601; t=1763645064; x=1764249864; 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=G8PxX49w5EzD4UFdp7KS/r9tDFhJ08WKJg91+BqmaAY=; b=0uYfHLY43FJDmE/SOb/HZKj+RXb0Uku8tf2XRiML3LAsoRZve1/nwwB4lzq1q8f0/j 08JmnjD/ebPJocbIWHiDVstkScr1agn5jJv2JqKWDSx7Yu9Bv0knLY4AtQVClppR5IZ3 CzveYHyAtsSUzVfCWzUfdObS4dhDIO46GCa1OAoCt32FkAoic+g3WYWo3PNsIWEmb2tb BJ78HhazpTEU9VqflHg9uugbwMLKVn5lY+hnjgqPd0z23vrbHywxJTknva98MVxfdNLU ioNj285srjUB7HOPeX2/XYAu+o9pukJOPGB4YSSiFqiyCwaVwQ9g9VmjXe8PGalwlw9j JroQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763645064; x=1764249864; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=G8PxX49w5EzD4UFdp7KS/r9tDFhJ08WKJg91+BqmaAY=; b=dJMk0Z8vl5kT4yQeOXx/qvrRa+nRReqNpraz7Aus+ih5oH6Ti8Jvd+iZUzaII3qy7z zzAJv6Bx4zqjWHFVd1Kjbh6CPrWDH1cxZvP0YiDkMqjbA7a7pr5kKiL7veAgwO93YhVQ /QzE9n6Y5o9ZHVsx4BrgcIpE3Sl8iRBEOxu6QPlh8uivP38cRfyI1j3AkwdLWpzKU7eI po7XdF/C4ZZvqOpL3gsxwFO9FdcKdQWwh3zKOajDmQ0lUGz8jpdiSaADtXZIKQfdl3wq WqZWfg2YuI5N+oFLL50xg7PEzZXjlUVAh08CMlnqaCLETcU5QuwUTSdxPjV192UJSigA Yr3A== X-Forwarded-Encrypted: i=1; AJvYcCVh5fcu3taJ8ROCXtRZ/fj53xYymVnILA1Qzk3bQzA7QhSv/EMbqeLWiVzwCqjezoLr71sMj+4D1Zjpk0A=@vger.kernel.org X-Gm-Message-State: AOJu0Yy6AjnNsp1vNXni+lrtX/JMfM9s64s+huvwLUzbkMmRN2cL45tj GlZCQXv1CxQYj6QvVqMQD7Ham1DW+wO1rMoUNpj0iG1Q+/t7SkP0zqQ/t7qewFdff+8= X-Gm-Gg: ASbGncu6emiUNdQBwof9aCP6kNrqvVjTSf6FayoUVKOof2VbONX6HdOn2J1SL97Zstk TrK2A5iokgk+Q1/tZaV/xE7jrcijyDg9liQ4HRNzcPb8UICMyiSgjuFI+7gPCMyNyJ/ehe3Rw63 MpHAUf+V60ygcM0PCGvbw+NzbmXcH/CE+p7FaoGBENE1CkkPZDG2hpZ3TLQi3dHJcYWMYsPUViw /0C1X9xY42g0RmYFlZH54Wfdbe0tzQLWCTWgaQKBVbkBjP4k63EJOy9EtAb7SOAeYKDJL7u6aCM mwUUUFmTA+b+bQnInDrVJ737Ed/rBy0Vl+nFiTNA5cEo0ooG3B3W/ZnDeeBodogREsTmRK3L+46 dq+zrPbiVe044KgR1YX5Tp7JEdv3FZwONlcBobAt9YrX9N87N6TVqTya5XEZUXgMdExW4CvTxii PXziE= X-Google-Smtp-Source: AGHT+IEPrIuvvvNMQFwqIyjWYN4SQgSzWiJ7h+dcP18/s+37GPMsHprp+4ehD4s+zAvJdXC3SMQrZQ== X-Received: by 2002:a05:600c:1549:b0:477:a9e:859a with SMTP id 5b1f17b1804b1-477b8a8a611mr29954055e9.22.1763645063647; Thu, 20 Nov 2025 05:24:23 -0800 (PST) Received: from [127.0.1.1] ([2a01:cb1d:dc:7e00:37af:6c1f:28a:47d2]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-477b82cc72dsm46762935e9.1.2025.11.20.05.24.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 20 Nov 2025 05:24:21 -0800 (PST) From: Bartosz Golaszewski Date: Thu, 20 Nov 2025 14:24:04 +0100 Subject: [PATCH v7 9/9] 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: <20251120-reset-gpios-swnodes-v7-9-a100493a0f4b@linaro.org> References: <20251120-reset-gpios-swnodes-v7-0-a100493a0f4b@linaro.org> In-Reply-To: <20251120-reset-gpios-swnodes-v7-0-a100493a0f4b@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 , David Rhodes , Richard Fitzgerald , Mark Brown , Maciej Strozek , Charles Keepax , Andy Shevchenko , Bartosz Golaszewski Cc: linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org, linux-sound@vger.kernel.org, patches@opensource.cirrus.com, linux-spi@vger.kernel.org, Bartosz Golaszewski X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=7100; i=bartosz.golaszewski@linaro.org; h=from:subject:message-id; bh=LjGY9Q7mtS01FVXkHDotI+zXY3Fvxr3o/OlPgyLk0TI=; b=owEBbQKS/ZANAwAKAQWdLsv/NoTDAcsmYgBpHxZ14gj5DrBF7BjfQSYkrPkMGdchXL7C84cpA KldwESHuaaJAjMEAAEKAB0WIQSR5RMt5bVGHXuiZfwFnS7L/zaEwwUCaR8WdQAKCRAFnS7L/zaE w0XKEACEAckJGFkSrLISJsfqUyT4xiT9YfJMF2gB9kxRNAxwghciygZ9f7VnTqHyPNatoNhoiw1 E4FHBgWoklBQfqNMPdNoS4RdB8d1nFYv4pen1wZ3pA814x5/Zx4S9qC+L/xqiibxLN6MrfW8LMy 6WHIQ1P5B4yUmpZI1A1DqFMv5upZ35nbbKyDLa8yRxjuROC+Nt75mYI9mxwWlSvvcoVqu1OGqG2 mHUWjUrU8JzKMw+R7NXKm3gV1fyn7qJNrIMd1GspbBlPSv0hga5fC25ZZw5EMFWZ9WFeNyGSMlH Z6yG/tZJHsUxKs1SPAHy4F+92oJ3jPNEPJfImCDEEsMGVgxoo5IcV2wGvVw+6/puCLagj+zTNaT wpey8oRdiAZ8XXSFCGJmpj/8cETs0mtAyXTV1eoBduLE+pAyglmdcurRcPkY1acTFK9xVZp1G4m 1gt3Ux14aD3BaTFEjUnWfzrtFw0cYwpZDQQvjo5McStw2E5JkAvvChn7PH36+sKqKf+bpjwliTY asDaM2+Jn6np80FewW2ZmGgfSSL5osa0R84Uhq3TsawQxqB29OMN1GHbVXuNmJO7S3EbAdBusjP fMIfEls4PbOZYNd+6564Cvf46pp2hZxWYXIAiJI0uKqg+516JCILSzGl5cTmKkdMju8ggW1FU6T z6r0OwGdtHBUKsA== 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 Acked-by: Greg Kroah-Hartman Signed-off-by: Bartosz Golaszewski --- drivers/reset/core.c | 127 ++++++++++++++++++++++++++++++-----------------= ---- 1 file changed, 74 insertions(+), 53 deletions(-) diff --git a/drivers/reset/core.c b/drivers/reset/core.c index 1f5f8d85dc16142da3e3a9988f2737c83550cb2f..0135dd0ae20498396fdb5a682f9= 13b6048cb5750 100644 --- a/drivers/reset/core.c +++ b/drivers/reset/core.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -74,10 +75,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 @@ -819,52 +822,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 /* @@ -872,8 +868,10 @@ 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[2] =3D { }; + unsigned int offset, of_flags, lflags; struct reset_gpio_lookup *rgpio_dev; - struct auxiliary_device *adev; + struct device *parent; int id, ret; =20 /* @@ -892,6 +890,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) @@ -906,6 +921,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; @@ -917,11 +936,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 @@ -929,19 +943,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