From patchwork Fri Jul 3 12:21:23 2020
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
X-Patchwork-Submitter: Pratyush Yadav
X-Patchwork-Id: 1322355
X-Patchwork-Delegate: trini@ti.com
Return-Path:
X-Original-To: incoming@patchwork.ozlabs.org
Delivered-To: patchwork-incoming@bilbo.ozlabs.org
Authentication-Results: ozlabs.org;
spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de
(client-ip=85.214.62.61; helo=phobos.denx.de;
envelope-from=u-boot-bounces@lists.denx.de; receiver=)
Authentication-Results: ozlabs.org;
dmarc=pass (p=quarantine dis=none) header.from=ti.com
Authentication-Results: ozlabs.org;
dkim=pass (1024-bit key;
unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256
header.s=ti-com-17Q1 header.b=OlYhSwh7;
dkim-atps=neutral
Received: from phobos.denx.de (phobos.denx.de [85.214.62.61])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest
SHA256)
(No client certificate requested)
by ozlabs.org (Postfix) with ESMTPS id 49yvGX6Rsvz9sPF
for ; Fri, 3 Jul 2020 22:21:56 +1000 (AEST)
Received: from h2850616.stratoserver.net (localhost [IPv6:::1])
by phobos.denx.de (Postfix) with ESMTP id D4E2081B8D;
Fri, 3 Jul 2020 14:21:39 +0200 (CEST)
Authentication-Results: phobos.denx.de;
dmarc=pass (p=quarantine dis=none) header.from=ti.com
Authentication-Results: phobos.denx.de;
spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de
Authentication-Results: phobos.denx.de;
dkim=pass (1024-bit key;
unprotected) header.d=ti.com header.i=@ti.com header.b="OlYhSwh7";
dkim-atps=neutral
Received: by phobos.denx.de (Postfix, from userid 109)
id 1FB8781B65; Fri, 3 Jul 2020 14:21:36 +0200 (CEST)
X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de
X-Spam-Level:
X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,
DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H3,
RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham
autolearn_force=no version=3.4.2
Received: from lelv0143.ext.ti.com (lelv0143.ext.ti.com [198.47.23.248])
(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
(No client certificate requested)
by phobos.denx.de (Postfix) with ESMTPS id 10C0381B47
for ; Fri, 3 Jul 2020 14:21:31 +0200 (CEST)
Authentication-Results: phobos.denx.de;
dmarc=pass (p=quarantine dis=none) header.from=ti.com
Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com
Received: from lelv0265.itg.ti.com ([10.180.67.224])
by lelv0143.ext.ti.com (8.15.2/8.15.2) with ESMTP id 063CLT4Q084235;
Fri, 3 Jul 2020 07:21:29 -0500
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com;
s=ti-com-17Q1; t=1593778889;
bh=Cs1HkVSK6Ce0/Dm15h6zfwLWgProCgnfOWDifTND3dw=;
h=From:To:CC:Subject:Date:In-Reply-To:References;
b=OlYhSwh7pSUmwnyEoMexKjQBDxHAOA5m0omEEVkw1UQjB/TGuzL7U3KLPxr8w/NXJ
Pyxanrf6zdk35LjsmCtUFlaJTv+KDltZON42TtFtMZnEeOGxqScMQAtevsxQ39eTCf
5I730tv3GF1sZa0jL5nJfxSjMSWA4uwpS2FX3OMk=
Received: from DLEE109.ent.ti.com (dlee109.ent.ti.com [157.170.170.41])
by lelv0265.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 063CLTnc103256
(version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL);
Fri, 3 Jul 2020 07:21:29 -0500
Received: from DLEE107.ent.ti.com (157.170.170.37) by DLEE109.ent.ti.com
(157.170.170.41) with Microsoft SMTP Server (version=TLS1_2,
cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3; Fri, 3 Jul
2020 07:21:29 -0500
Received: from fllv0040.itg.ti.com (10.64.41.20) by DLEE107.ent.ti.com
(157.170.170.37) with Microsoft SMTP Server (version=TLS1_2,
cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3 via
Frontend Transport; Fri, 3 Jul 2020 07:21:29 -0500
Received: from pratyush-OptiPlex-790.dhcp.ti.com (ileax41-snat.itg.ti.com
[10.172.224.153])
by fllv0040.itg.ti.com (8.15.2/8.15.2) with ESMTP id 063CLPaS060615;
Fri, 3 Jul 2020 07:21:28 -0500
From: Pratyush Yadav
To: Simon Glass ,
CC: Pratyush Yadav , Vignesh Raghavendra ,
Sekhar Nori
Subject: [PATCH v3 1/2] drivers: gpio: Add a managed API to get a GPIO from
the device-tree
Date: Fri, 3 Jul 2020 17:51:23 +0530
Message-ID: <20200703122124.29854-2-p.yadav@ti.com>
X-Mailer: git-send-email 2.25.0
In-Reply-To: <20200703122124.29854-1-p.yadav@ti.com>
References: <20200703122124.29854-1-p.yadav@ti.com>
MIME-Version: 1.0
X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180
X-BeenThere: u-boot@lists.denx.de
X-Mailman-Version: 2.1.34
Precedence: list
List-Id: U-Boot discussion
List-Unsubscribe: ,
List-Archive:
List-Post:
List-Help:
List-Subscribe: ,
Errors-To: u-boot-bounces@lists.denx.de
Sender: "U-Boot"
X-Virus-Scanned: clamav-milter 0.102.3 at phobos.denx.de
X-Virus-Status: Clean
From: Jean-Jacques Hiblot
Add managed functions to get a gpio from the devce-tree, based on a
property name (minus the '-gpios' suffix) and optionally an index.
When the device is unbound, the GPIO is automatically released and the
data structure is freed.
Signed-off-by: Jean-Jacques Hiblot
Reviewed-by: Simon Glass
Signed-off-by: Pratyush Yadav
---
drivers/gpio/gpio-uclass.c | 71 ++++++++++++++++++++++++++++++++++++++
include/asm-generic/gpio.h | 47 +++++++++++++++++++++++++
2 files changed, 118 insertions(+)
--
2.27.0
diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index 9eeab22eef..c460ebc63b 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -6,6 +6,8 @@
#include
#include
#include
+#include
+#include
#include
#include
#include
@@ -1141,6 +1143,75 @@ int gpio_dev_request_index(struct udevice *dev, const char *nodename,
flags, 0, dev);
}
+static void devm_gpiod_release(struct udevice *dev, void *res)
+{
+ dm_gpio_free(dev, res);
+}
+
+static int devm_gpiod_match(struct udevice *dev, void *res, void *data)
+{
+ return res == data;
+}
+
+struct gpio_desc *devm_gpiod_get_index(struct udevice *dev, const char *id,
+ unsigned int index, int flags)
+{
+ int rc;
+ struct gpio_desc *desc;
+ char *propname;
+ static const char suffix[] = "-gpios";
+
+ propname = malloc(strlen(id) + sizeof(suffix));
+ if (!propname) {
+ rc = -ENOMEM;
+ goto end;
+ }
+
+ strcpy(propname, id);
+ strcat(propname, suffix);
+
+ desc = devres_alloc(devm_gpiod_release, sizeof(struct gpio_desc),
+ __GFP_ZERO);
+ if (unlikely(!desc)) {
+ rc = -ENOMEM;
+ goto end;
+ }
+
+ rc = gpio_request_by_name(dev, propname, index, desc, flags);
+
+end:
+ if (propname)
+ free(propname);
+
+ if (rc)
+ return ERR_PTR(rc);
+
+ devres_add(dev, desc);
+
+ return desc;
+}
+
+struct gpio_desc *devm_gpiod_get_index_optional(struct udevice *dev,
+ const char *id,
+ unsigned int index,
+ int flags)
+{
+ struct gpio_desc *desc = devm_gpiod_get_index(dev, id, index, flags);
+
+ if (IS_ERR(desc))
+ return NULL;
+
+ return desc;
+}
+
+void devm_gpiod_put(struct udevice *dev, struct gpio_desc *desc)
+{
+ int rc;
+
+ rc = devres_release(dev, devm_gpiod_release, devm_gpiod_match, desc);
+ WARN_ON(rc);
+}
+
static int gpio_post_bind(struct udevice *dev)
{
struct udevice *child;
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index e16c2f31d9..76e0e902c4 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -674,4 +674,51 @@ int dm_gpio_get_dir_flags(struct gpio_desc *desc, ulong *flags);
*/
int gpio_get_number(const struct gpio_desc *desc);
+/**
+ * devm_gpiod_get_index - Resource-managed gpiod_get()
+ * @dev: GPIO consumer
+ * @con_id: function within the GPIO consumer
+ * @index: index of the GPIO to obtain in the consumer
+ * @flags: optional GPIO initialization flags
+ *
+ * Managed gpiod_get(). GPIO descriptors returned from this function are
+ * automatically disposed on driver detach.
+ * Return the GPIO descriptor corresponding to the function con_id of device
+ * dev, -ENOENT if no GPIO has been assigned to the requested function, or
+ * another IS_ERR() code if an error occurred while trying to acquire the GPIO.
+ */
+struct gpio_desc *devm_gpiod_get_index(struct udevice *dev, const char *id,
+ unsigned int index, int flags);
+
+#define devm_gpiod_get(dev, id, flags) devm_gpiod_get_index(dev, id, 0, flags)
+/**
+ * gpiod_get_optional - obtain an optional GPIO for a given GPIO function
+ * @dev: GPIO consumer, can be NULL for system-global GPIOs
+ * @con_id: function within the GPIO consumer
+ * @index: index of the GPIO to obtain in the consumer
+ * @flags: optional GPIO initialization flags
+ *
+ * This is equivalent to devm_gpiod_get(), except that when no GPIO was
+ * assigned to the requested function it will return NULL. This is convenient
+ * for drivers that need to handle optional GPIOs.
+ */
+struct gpio_desc *devm_gpiod_get_index_optional(struct udevice *dev,
+ const char *id,
+ unsigned int index,
+ int flags);
+
+#define devm_gpiod_get_optional(dev, id, flags) \
+ devm_gpiod_get_index_optional(dev, id, 0, flags)
+
+/**
+ * devm_gpiod_put - Resource-managed gpiod_put()
+ * @dev: GPIO consumer
+ * @desc: GPIO descriptor to dispose of
+ *
+ * Dispose of a GPIO descriptor obtained with devm_gpiod_get() or
+ * devm_gpiod_get_index(). Normally this function will not be called as the GPIO
+ * will be disposed of by the resource management code.
+ */
+void devm_gpiod_put(struct udevice *dev, struct gpio_desc *desc);
+
#endif /* _ASM_GENERIC_GPIO_H_ */
From patchwork Fri Jul 3 12:21:24 2020
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
X-Patchwork-Submitter: Pratyush Yadav
X-Patchwork-Id: 1322356
X-Patchwork-Delegate: trini@ti.com
Return-Path:
X-Original-To: incoming@patchwork.ozlabs.org
Delivered-To: patchwork-incoming@bilbo.ozlabs.org
Authentication-Results: ozlabs.org;
spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de
(client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de;
envelope-from=u-boot-bounces@lists.denx.de; receiver=)
Authentication-Results: ozlabs.org;
dmarc=pass (p=quarantine dis=none) header.from=ti.com
Authentication-Results: ozlabs.org;
dkim=pass (1024-bit key;
unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256
header.s=ti-com-17Q1 header.b=HPAEAPUZ;
dkim-atps=neutral
Received: from phobos.denx.de (phobos.denx.de
[IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01])
(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
key-exchange X25519 server-signature RSA-PSS (4096 bits))
(No client certificate requested)
by ozlabs.org (Postfix) with ESMTPS id 49yvGj710Cz9sPF
for ; Fri, 3 Jul 2020 22:22:05 +1000 (AEST)
Received: from h2850616.stratoserver.net (localhost [IPv6:::1])
by phobos.denx.de (Postfix) with ESMTP id 0D57E81BAE;
Fri, 3 Jul 2020 14:21:42 +0200 (CEST)
Authentication-Results: phobos.denx.de;
dmarc=pass (p=quarantine dis=none) header.from=ti.com
Authentication-Results: phobos.denx.de;
spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de
Authentication-Results: phobos.denx.de;
dkim=pass (1024-bit key;
unprotected) header.d=ti.com header.i=@ti.com header.b="HPAEAPUZ";
dkim-atps=neutral
Received: by phobos.denx.de (Postfix, from userid 109)
id 2D71D81B54; Fri, 3 Jul 2020 14:21:38 +0200 (CEST)
X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de
X-Spam-Level:
X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,
DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RCVD_IN_MSPIKE_H3,
RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham
autolearn_force=no version=3.4.2
Received: from lelv0142.ext.ti.com (lelv0142.ext.ti.com [198.47.23.249])
(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
(No client certificate requested)
by phobos.denx.de (Postfix) with ESMTPS id 64A2081B54
for ; Fri, 3 Jul 2020 14:21:33 +0200 (CEST)
Authentication-Results: phobos.denx.de;
dmarc=pass (p=quarantine dis=none) header.from=ti.com
Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com
Received: from fllv0034.itg.ti.com ([10.64.40.246])
by lelv0142.ext.ti.com (8.15.2/8.15.2) with ESMTP id 063CLVZ3005301;
Fri, 3 Jul 2020 07:21:31 -0500
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com;
s=ti-com-17Q1; t=1593778891;
bh=oezg71xZMtqW/5/jWC9MC5uUaSHRt8n5+7R8HZgiJ/g=;
h=From:To:CC:Subject:Date:In-Reply-To:References;
b=HPAEAPUZqqGKNh8io62ksZikxc6A+uPL/XOLZ2vkzSM2a1holwHIQF1Q5PXRguV8n
G5R4j1uyMKKOSMKpTFbid1Y5bQ5Ja1tpi5Pv+umnCIDZddp7oAkDOxkXY+XwVqGClP
/QI+cFPwvCrIvbgKSg2rw3o5lwB189IH6wDxMLks=
Received: from DFLE112.ent.ti.com (dfle112.ent.ti.com [10.64.6.33])
by fllv0034.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 063CLVVM115100
(version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL);
Fri, 3 Jul 2020 07:21:31 -0500
Received: from DFLE115.ent.ti.com (10.64.6.36) by DFLE112.ent.ti.com
(10.64.6.33) with Microsoft SMTP Server (version=TLS1_2,
cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3; Fri, 3 Jul
2020 07:21:31 -0500
Received: from fllv0040.itg.ti.com (10.64.41.20) by DFLE115.ent.ti.com
(10.64.6.36) with Microsoft SMTP Server (version=TLS1_2,
cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3 via
Frontend Transport; Fri, 3 Jul 2020 07:21:31 -0500
Received: from pratyush-OptiPlex-790.dhcp.ti.com (ileax41-snat.itg.ti.com
[10.172.224.153])
by fllv0040.itg.ti.com (8.15.2/8.15.2) with ESMTP id 063CLPaT060615;
Fri, 3 Jul 2020 07:21:30 -0500
From: Pratyush Yadav
To: Simon Glass ,
CC: Pratyush Yadav , Vignesh Raghavendra ,
Sekhar Nori
Subject: [PATCH v3 2/2] test: gpio: Add tests for the managed API
Date: Fri, 3 Jul 2020 17:51:24 +0530
Message-ID: <20200703122124.29854-3-p.yadav@ti.com>
X-Mailer: git-send-email 2.25.0
In-Reply-To: <20200703122124.29854-1-p.yadav@ti.com>
References: <20200703122124.29854-1-p.yadav@ti.com>
MIME-Version: 1.0
X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180
X-BeenThere: u-boot@lists.denx.de
X-Mailman-Version: 2.1.34
Precedence: list
List-Id: U-Boot discussion
List-Unsubscribe: ,
List-Archive:
List-Post:
List-Help:
List-Subscribe: ,
Errors-To: u-boot-bounces@lists.denx.de
Sender: "U-Boot"
X-Virus-Scanned: clamav-milter 0.102.3 at phobos.denx.de
X-Virus-Status: Clean
From: Jean-Jacques Hiblot
Add a test to verify that GPIOs can be acquired/released using the managed
API. Also check that the GPIOs are released when the consumer device is
removed.
Signed-off-by: Jean-Jacques Hiblot
Reviewed-by: Simon Glass
Signed-off-by: Pratyush Yadav
---
arch/sandbox/dts/test.dts | 10 ++++
test/dm/gpio.c | 102 ++++++++++++++++++++++++++++++++++++++
2 files changed, 112 insertions(+)
--
2.27.0
diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts
index 5ce5e28476..a8618ccade 100644
--- a/arch/sandbox/dts/test.dts
+++ b/arch/sandbox/dts/test.dts
@@ -107,6 +107,9 @@
<&gpio_c 5 GPIO_IN>,
<&gpio_c 6 (GPIO_ACTIVE_LOW|GPIO_OUT|GPIO_OPEN_DRAIN)>,
<&gpio_c 7 (GPIO_ACTIVE_LOW|GPIO_OUT|GPIO_OPEN_SOURCE)>;
+ test4-gpios = <&gpio_a 14>, <&gpio_b 4 1 3 2 1>;
+ test5-gpios = <&gpio_a 19>;
+
int-value = <1234>;
uint-value = <(-1234)>;
int64-value = /bits/ 64 <0x1111222233334444>;
@@ -114,6 +117,13 @@
interrupts-extended = <&irq 3 0>;
};
+ another-test {
+ reg = <0 2>;
+ compatible = "denx,u-boot-fdt-test";
+ test4-gpios = <&gpio_a 14>, <&gpio_b 4 1 3 2 1>;
+ test5-gpios = <&gpio_a 19>;
+ };
+
junk {
reg = <1 1>;
compatible = "not,compatible";
diff --git a/test/dm/gpio.c b/test/dm/gpio.c
index b5ee4e4f87..40bea32b13 100644
--- a/test/dm/gpio.c
+++ b/test/dm/gpio.c
@@ -8,6 +8,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -385,3 +386,104 @@ static int dm_test_gpio_get_dir_flags(struct unit_test_state *uts)
return 0;
}
DM_TEST(dm_test_gpio_get_dir_flags, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test that we can get/release GPIOs using managed API */
+static int dm_test_gpio_devm(struct unit_test_state *uts)
+{
+ static const u32 flags = GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE;
+ struct gpio_desc *desc1, *desc2, *desc3, *desc_err;
+ struct udevice *dev;
+ struct udevice *dev2;
+
+ ut_assertok(uclass_get_device_by_name(UCLASS_TEST_FDT, "a-test",
+ &dev));
+ ut_assertok(uclass_get_device_by_name(UCLASS_TEST_FDT, "another-test",
+ &dev2));
+
+ /* Get 3 GPIOs from 'a-test' dev */
+ desc1 = devm_gpiod_get_index(dev, "test4", 0, flags);
+ ut_assert(!IS_ERR(desc1));
+ desc2 = devm_gpiod_get_index(dev, "test4", 1, flags);
+ ut_assert(!IS_ERR(desc2));
+ desc3 = devm_gpiod_get_index_optional(dev, "test5", 0, flags);
+ ut_assert(!IS_ERR(desc3));
+ ut_assert(desc3);
+
+ /*
+ * Try get the same 3 GPIOs from 'a-test' and 'another-test' devices.
+ * check that it fails
+ */
+ desc_err = devm_gpiod_get_index(dev, "test4", 0, flags);
+ ut_asserteq(-EBUSY, PTR_ERR(desc_err));
+ desc_err = devm_gpiod_get_index(dev2, "test4", 0, flags);
+ ut_asserteq(-EBUSY, PTR_ERR(desc_err));
+ desc_err = devm_gpiod_get_index(dev, "test4", 1, flags);
+ ut_asserteq(-EBUSY, PTR_ERR(desc_err));
+ desc_err = devm_gpiod_get_index(dev2, "test4", 1, flags);
+ ut_asserteq(-EBUSY, PTR_ERR(desc_err));
+ desc_err = devm_gpiod_get_index_optional(dev, "test5", 0, flags);
+ ut_asserteq_ptr(NULL, desc_err);
+ desc_err = devm_gpiod_get_index_optional(dev2, "test5", 0, flags);
+ ut_asserteq_ptr(NULL, desc_err);
+
+ /* Try get GPIOs outside of the list */
+ desc_err = devm_gpiod_get_index(dev, "test4", 2, flags);
+ ut_assert(IS_ERR(desc_err));
+ desc_err = devm_gpiod_get_index_optional(dev, "test5", 1, flags);
+ ut_asserteq_ptr(NULL, desc_err);
+
+ /* Manipulate the GPIOs */
+ ut_assertok(dm_gpio_set_value(desc1, 1));
+ ut_asserteq(1, dm_gpio_get_value(desc1));
+ ut_assertok(dm_gpio_set_value(desc1, 0));
+ ut_asserteq(0, dm_gpio_get_value(desc1));
+
+ ut_assertok(dm_gpio_set_value(desc2, 1));
+ ut_asserteq(1, dm_gpio_get_value(desc2));
+ ut_assertok(dm_gpio_set_value(desc2, 0));
+ ut_asserteq(0, dm_gpio_get_value(desc2));
+
+ ut_assertok(dm_gpio_set_value(desc3, 1));
+ ut_asserteq(1, dm_gpio_get_value(desc3));
+ ut_assertok(dm_gpio_set_value(desc3, 0));
+ ut_asserteq(0, dm_gpio_get_value(desc3));
+
+ /* Check that the GPIO cannot be owned by more than one device */
+ desc_err = devm_gpiod_get_index(dev2, "test4", 0, flags);
+ ut_asserteq(-EBUSY, PTR_ERR(desc_err));
+ desc_err = devm_gpiod_get_index(dev2, "test4", 1, flags);
+ ut_asserteq(-EBUSY, PTR_ERR(desc_err));
+ desc_err = devm_gpiod_get_index_optional(dev2, "test5", 0, flags);
+ ut_asserteq_ptr(NULL, desc_err);
+
+ /*
+ * Release one GPIO and check that we can get it back using
+ * 'another-test' and then 'a-test'
+ */
+ devm_gpiod_put(dev, desc2);
+ desc2 = devm_gpiod_get_index(dev2, "test4", 1, flags);
+ ut_assert(!IS_ERR(desc2));
+
+ devm_gpiod_put(dev2, desc2);
+ desc2 = devm_gpiod_get_index(dev, "test4", 1, flags);
+ ut_assert(!IS_ERR(desc2));
+
+ /* Release one GPIO before removing the 'a-test' dev. */
+ devm_gpiod_put(dev, desc2);
+ device_remove(dev, DM_REMOVE_NORMAL);
+
+ /* All the GPIOs must have been freed. We should be able to claim
+ * them with the 'another-test' device.
+ */
+ desc1 = devm_gpiod_get_index(dev2, "test4", 0, flags);
+ ut_assert(!IS_ERR(desc1));
+ desc2 = devm_gpiod_get_index(dev2, "test4", 1, flags);
+ ut_assert(!IS_ERR(desc2));
+ desc3 = devm_gpiod_get_index_optional(dev2, "test5", 0, flags);
+ ut_assert(!IS_ERR(desc3));
+ ut_assert(desc3);
+
+ device_remove(dev2, DM_REMOVE_NORMAL);
+ return 0;
+}
+DM_TEST(dm_test_gpio_devm, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);