All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kent Gibson <warthog618@gmail.com>
To: linux-gpio@vger.kernel.org, bgolaszewski@baylibre.com,
	linus.walleij@linaro.org, bamv2005@gmail.com
Cc: drew@pdp7.com, thomas.petazzoni@bootlin.com,
	Kent Gibson <warthog618@gmail.com>
Subject: [PATCH v6 7/7] gpio: add new SET_CONFIG ioctl() to gpio chardev
Date: Tue,  5 Nov 2019 10:04:29 +0800	[thread overview]
Message-ID: <20191105020429.18942-8-warthog618@gmail.com> (raw)
In-Reply-To: <20191105020429.18942-1-warthog618@gmail.com>

Add the GPIOHANDLE_SET_CONFIG_IOCTL to the gpio chardev.
The ioctl allows some of the configuration of a requested handle to be
changed without having to release the line.
The primary use case is the changing of direction for bi-directional
lines.

Based on initial work by Bartosz Golaszewski <bgolaszewski@baylibre.com>

Signed-off-by: Kent Gibson <warthog618@gmail.com>
---
 drivers/gpio/gpiolib.c    | 69 +++++++++++++++++++++++++++++++++++++++
 include/uapi/linux/gpio.h | 18 ++++++++++
 2 files changed, 87 insertions(+)

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 8d6e5dd3d1cf..f46aa763ee6f 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -476,6 +476,73 @@ static int linehandle_validate_flags(u32 flags)
 	return 0;
 }
 
+static void linehandle_configure_flag(unsigned long *flagsp,
+				      u32 bit, bool active)
+{
+	if (active)
+		set_bit(bit, flagsp);
+	else
+		clear_bit(bit, flagsp);
+}
+
+static long linehandle_set_config(struct linehandle_state *lh,
+				  void __user *ip)
+{
+	struct gpiohandle_config gcnf;
+	struct gpio_desc *desc;
+	int i, ret;
+	u32 lflags;
+	unsigned long *flagsp;
+
+	if (copy_from_user(&gcnf, ip, sizeof(gcnf)))
+		return -EFAULT;
+
+	lflags = gcnf.flags;
+	ret = linehandle_validate_flags(lflags);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < lh->numdescs; i++) {
+		desc = lh->descs[i];
+		flagsp = &desc->flags;
+
+		linehandle_configure_flag(flagsp, FLAG_ACTIVE_LOW,
+			lflags & GPIOHANDLE_REQUEST_ACTIVE_LOW);
+
+		linehandle_configure_flag(flagsp, FLAG_OPEN_DRAIN,
+			lflags & GPIOHANDLE_REQUEST_OPEN_DRAIN);
+
+		linehandle_configure_flag(flagsp, FLAG_OPEN_SOURCE,
+			lflags & GPIOHANDLE_REQUEST_OPEN_SOURCE);
+
+		linehandle_configure_flag(flagsp, FLAG_PULL_UP,
+			lflags & GPIOHANDLE_REQUEST_BIAS_PULL_UP);
+
+		linehandle_configure_flag(flagsp, FLAG_PULL_DOWN,
+			lflags & GPIOHANDLE_REQUEST_BIAS_PULL_DOWN);
+
+		linehandle_configure_flag(flagsp, FLAG_BIAS_DISABLE,
+			lflags & GPIOHANDLE_REQUEST_BIAS_DISABLE);
+
+		/*
+		 * Lines have to be requested explicitly for input
+		 * or output, else the line will be treated "as is".
+		 */
+		if (lflags & GPIOHANDLE_REQUEST_OUTPUT) {
+			int val = !!gcnf.default_values[i];
+
+			ret = gpiod_direction_output(desc, val);
+			if (ret)
+				return ret;
+		} else if (lflags & GPIOHANDLE_REQUEST_INPUT) {
+			ret = gpiod_direction_input(desc);
+			if (ret)
+				return ret;
+		}
+	}
+	return 0;
+}
+
 static long linehandle_ioctl(struct file *filep, unsigned int cmd,
 			     unsigned long arg)
 {
@@ -526,6 +593,8 @@ static long linehandle_ioctl(struct file *filep, unsigned int cmd,
 					      lh->descs,
 					      NULL,
 					      vals);
+	} else if (cmd == GPIOHANDLE_SET_CONFIG_IOCTL) {
+		return linehandle_set_config(lh, ip);
 	}
 	return -EINVAL;
 }
diff --git a/include/uapi/linux/gpio.h b/include/uapi/linux/gpio.h
index 7cc21c3b0839..799cf823d493 100644
--- a/include/uapi/linux/gpio.h
+++ b/include/uapi/linux/gpio.h
@@ -100,6 +100,24 @@ struct gpiohandle_request {
 	int fd;
 };
 
+/**
+ * struct gpiohandle_config - Configuration for a GPIO handle request
+ * @flags: updated flags for the requested GPIO lines, such as
+ * GPIOHANDLE_REQUEST_OUTPUT, GPIOHANDLE_REQUEST_ACTIVE_LOW etc, OR:ed
+ * together
+ * @default_values: if the GPIOHANDLE_REQUEST_OUTPUT is set in flags,
+ * this specifies the default output value, should be 0 (low) or
+ * 1 (high), anything else than 0 or 1 will be interpreted as 1 (high)
+ * @padding: reserved for future use and should be zero filled
+ */
+struct gpiohandle_config {
+	__u32 flags;
+	__u8 default_values[GPIOHANDLES_MAX];
+	__u32 padding[4]; /* padding for future use */
+};
+
+#define GPIOHANDLE_SET_CONFIG_IOCTL _IOWR(0xB4, 0x0a, struct gpiohandle_config)
+
 /**
  * struct gpiohandle_data - Information of values on a GPIO handle
  * @values: when getting the state of lines this contains the current
-- 
2.23.0


  parent reply	other threads:[~2019-11-05  2:05 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-05  2:04 [PATCH v6 0/7] gpio: expose line bias flags to userspace Kent Gibson
2019-11-05  2:04 ` [PATCH v6 1/7] gpio: expose pull-up/pull-down line " Kent Gibson
2019-11-05  2:04 ` [PATCH v6 2/7] gpiolib: add support for pull up/down to lineevent_create Kent Gibson
2019-11-05  2:04 ` [PATCH v6 3/7] gpiolib: add support for disabling line bias Kent Gibson
2019-11-05  2:04 ` [PATCH v6 4/7] gpiolib: add support for biasing output lines Kent Gibson
2019-11-06 19:39   ` Drew Fustini
2019-11-06 23:56     ` Kent Gibson
2019-11-05  2:04 ` [PATCH v6 5/7] gpio: mockup: add set_config to support pull up/down Kent Gibson
2019-11-05  2:04 ` [PATCH v6 6/7] gpiolib: move validation of line handle flags into helper function Kent Gibson
2019-11-05  2:04 ` Kent Gibson [this message]
2019-11-05 15:05 ` [PATCH v6 0/7] gpio: expose line bias flags to userspace Bartosz Golaszewski
2019-11-07  8:10   ` Linus Walleij
2019-11-05 15:26 ` Kent Gibson
2019-11-05 16:24   ` Bartosz Golaszewski
2019-11-05 21:07     ` Bartosz Golaszewski
2019-11-06  6:48       ` Kent Gibson
2019-11-06 13:59         ` Bartosz Golaszewski
2019-11-06 16:58           ` Kent Gibson
2019-11-06 17:06             ` Bartosz Golaszewski
2019-11-06 23:20               ` Kent Gibson
2019-11-07 10:39             ` Kent Gibson
2019-11-07 11:28               ` Bartosz Golaszewski
2019-11-07 12:18                 ` Kent Gibson
2019-11-05 23:15     ` Kent Gibson
2019-11-07 17:57 ` Bartosz Golaszewski
2020-04-15 14:03 ` boards to test gpio line bias flags? Drew Fustini

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=20191105020429.18942-8-warthog618@gmail.com \
    --to=warthog618@gmail.com \
    --cc=bamv2005@gmail.com \
    --cc=bgolaszewski@baylibre.com \
    --cc=drew@pdp7.com \
    --cc=linus.walleij@linaro.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=thomas.petazzoni@bootlin.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.