devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Andrew Jeffery <andrew@aj.id.au>
To: linux-gpio@vger.kernel.org
Cc: Andrew Jeffery <andrew@aj.id.au>,
	linus.walleij@linaro.org, corbet@lwn.net, joel@jms.id.au,
	ryan_chen@aspeedtech.com, robh+dt@kernel.org,
	frowand.list@gmail.com, ckeepax@opensource.wolfsonmicro.com,
	ldewangan@nvidia.com, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, patches@opensource.cirrus.com,
	devicetree@vger.kernel.org, openbmc@lists.ozlabs.org,
	linux-aspeed@lists.ozlabs.org
Subject: [RFC PATCH 4/5] gpio: gpiolib: Add sysfs support for maintaining GPIO values on reset
Date: Fri, 20 Oct 2017 14:07:26 +1030	[thread overview]
Message-ID: <20171020033727.21557-5-andrew@aj.id.au> (raw)
In-Reply-To: <20171020033727.21557-1-andrew@aj.id.au>

Expose a new 'maintain' sysfs attribute to control both suspend and
reset tolerance.

Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
---
 Documentation/gpio/sysfs.txt |  9 +++++
 drivers/gpio/gpiolib-sysfs.c | 88 ++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 93 insertions(+), 4 deletions(-)

diff --git a/Documentation/gpio/sysfs.txt b/Documentation/gpio/sysfs.txt
index aeab01aa4d00..f447f0746884 100644
--- a/Documentation/gpio/sysfs.txt
+++ b/Documentation/gpio/sysfs.txt
@@ -96,6 +96,15 @@ and have the following read/write attributes:
 		for "rising" and "falling" edges will follow this
 		setting.
 
+	"maintain" ... displays and controls whether the state of the GPIO is
+		maintained or lost on suspend or reset. The valid values take
+	        the following meanings:
+
+	        0: Do not maintain state on either suspend or reset
+	        1: Maintain state for suspend only
+	        2: Maintain state for reset only
+	        3: Maintain state for both suspend and reset
+
 GPIO controllers have paths like /sys/class/gpio/gpiochip42/ (for the
 controller implementing GPIOs starting at #42) and have the following
 read-only attributes:
diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c
index 3f454eaf2101..bfa186e73e26 100644
--- a/drivers/gpio/gpiolib-sysfs.c
+++ b/drivers/gpio/gpiolib-sysfs.c
@@ -289,6 +289,74 @@ static ssize_t edge_store(struct device *dev,
 }
 static DEVICE_ATTR_RW(edge);
 
+#define GPIOLIB_SYSFS_MAINTAIN_SUSPEND	BIT(0)
+#define GPIOLIB_SYSFS_MAINTAIN_RESET	BIT(1)
+#define GPIOLIB_SYSFS_MAINTAIN_ALL	GENMASK(1, 0)
+static ssize_t maintain_show(struct device *dev, struct device_attribute *attr,
+			     char *buf)
+{
+	struct gpiod_data *data = dev_get_drvdata(dev);
+	ssize_t	status = 0;
+	int val = 0;
+
+	mutex_lock(&data->mutex);
+
+	if (!test_bit(FLAG_SLEEP_MAY_LOSE_VALUE, &data->desc->flags))
+		val |= GPIOLIB_SYSFS_MAINTAIN_SUSPEND;
+
+	if (test_bit(FLAG_RESET_TOLERANT, &data->desc->flags))
+		val |= GPIOLIB_SYSFS_MAINTAIN_RESET;
+
+	status = sprintf(buf, "%d\n", val);
+
+	mutex_unlock(&data->mutex);
+
+	return status;
+}
+
+static ssize_t maintain_store(struct device *dev,
+			      struct device_attribute *attr,
+			      const char *buf,
+			      size_t size)
+{
+	struct gpiod_data *data = dev_get_drvdata(dev);
+	struct gpio_chip *chip;
+	ssize_t	status;
+	long provided;
+
+	mutex_lock(&data->mutex);
+
+	chip = data->desc->gdev->chip;
+
+	if (!chip->set_config)
+		return -ENOTSUPP;
+
+	status = kstrtol(buf, 0, &provided);
+	if (status < 0)
+		goto out;
+
+	if (provided & ~GPIOLIB_SYSFS_MAINTAIN_ALL) {
+		status = -EINVAL;
+		goto out;
+	}
+
+	if (!(provided & GPIOLIB_SYSFS_MAINTAIN_SUSPEND))
+		set_bit(FLAG_SLEEP_MAY_LOSE_VALUE, &data->desc->flags);
+	else
+		clear_bit(FLAG_SLEEP_MAY_LOSE_VALUE,
+			  &data->desc->flags);
+
+	/* Configure reset tolerance */
+	status = gpiod_set_reset_tolerant(data->desc,
+			!!(provided & GPIOLIB_SYSFS_MAINTAIN_RESET));
+out:
+	mutex_unlock(&data->mutex);
+
+	return status ? : size;
+
+}
+static DEVICE_ATTR_RW(maintain);
+
 /* Caller holds gpiod-data mutex. */
 static int gpio_sysfs_set_active_low(struct device *dev, int value)
 {
@@ -378,6 +446,7 @@ static struct attribute *gpio_attrs[] = {
 	&dev_attr_edge.attr,
 	&dev_attr_value.attr,
 	&dev_attr_active_low.attr,
+	&dev_attr_maintain.attr,
 	NULL,
 };
 
@@ -474,11 +543,22 @@ static ssize_t export_store(struct class *class,
 			status = -ENODEV;
 		goto done;
 	}
-	status = gpiod_export(desc, true);
-	if (status < 0)
+
+	/*
+	 * If userspace is requesting the GPIO via sysfs, make them explicitly
+	 * configure reset tolerance each time by unconditionally disabling it
+	 * here, as the export and configuration steps are not atomic.
+	 */
+	status = gpiod_set_reset_tolerant(desc, false);
+	if (status < 0) {
 		gpiod_free(desc);
-	else
-		set_bit(FLAG_SYSFS, &desc->flags);
+	} else {
+		status = gpiod_export(desc, true);
+		if (status < 0)
+			gpiod_free(desc);
+		else
+			set_bit(FLAG_SYSFS, &desc->flags);
+	}
 
 done:
 	if (status)
-- 
2.11.0

  parent reply	other threads:[~2017-10-20  3:37 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-20  3:37 [RFC PATCH 0/5] gpio: Expose reset tolerance capability Andrew Jeffery
2017-10-20  3:37 ` [RFC PATCH 1/5] gpio: gpiolib: Add core support for maintaining GPIO values on reset Andrew Jeffery
2017-10-20  7:17   ` Linus Walleij
2017-10-20  7:43     ` Linus Walleij
2017-10-20  8:32       ` Andrew Jeffery
2017-10-25  8:11         ` Charles Keepax
2017-10-26  0:00           ` Andrew Jeffery
2017-10-20  8:24     ` Andrew Jeffery
2017-10-20  3:37 ` [RFC PATCH 2/5] gpio: gpiolib: Add OF " Andrew Jeffery
     [not found]   ` <20171020033727.21557-3-andrew-zrmu5oMJ5Fs@public.gmane.org>
2017-10-20  7:18     ` Linus Walleij
2017-10-20  7:29       ` Andrew Jeffery
2017-10-20  3:37 ` [RFC PATCH 3/5] gpio: gpiolib: Add chardev " Andrew Jeffery
2017-10-20  7:27   ` Linus Walleij
2017-10-20  9:02     ` Andrew Jeffery
2017-10-25  8:14       ` Charles Keepax
2017-10-26  0:05         ` Andrew Jeffery
     [not found]           ` <1508976339.13477.5.camel-zrmu5oMJ5Fs@public.gmane.org>
2017-10-26  9:10             ` Charles Keepax
2017-10-31  9:59           ` Linus Walleij
2017-10-20  3:37 ` Andrew Jeffery [this message]
     [not found]   ` <20171020033727.21557-5-andrew-zrmu5oMJ5Fs@public.gmane.org>
2017-10-20  7:29     ` [RFC PATCH 4/5] gpio: gpiolib: Add sysfs " Linus Walleij
2017-10-20  7:40       ` Andrew Jeffery
2017-10-20  3:37 ` [RFC PATCH 5/5] gpio: aspeed: Add support for reset tolerance Andrew Jeffery

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171020033727.21557-5-andrew@aj.id.au \
    --to=andrew@aj.id.au \
    --cc=ckeepax@opensource.wolfsonmicro.com \
    --cc=corbet@lwn.net \
    --cc=devicetree@vger.kernel.org \
    --cc=frowand.list@gmail.com \
    --cc=joel@jms.id.au \
    --cc=ldewangan@nvidia.com \
    --cc=linus.walleij@linaro.org \
    --cc=linux-aspeed@lists.ozlabs.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=openbmc@lists.ozlabs.org \
    --cc=patches@opensource.cirrus.com \
    --cc=robh+dt@kernel.org \
    --cc=ryan_chen@aspeedtech.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).