From: Kent Gibson <warthog618@gmail.com>
To: linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org,
bgolaszewski@baylibre.com, linus.walleij@linaro.org
Cc: Kent Gibson <warthog618@gmail.com>
Subject: [PATCH v3 08/18] gpiolib: cdev: support GPIO_V2_LINE_SET_CONFIG_IOCTL
Date: Sun, 9 Aug 2020 21:25:19 +0800 [thread overview]
Message-ID: <20200809132529.264312-9-warthog618@gmail.com> (raw)
In-Reply-To: <20200809132529.264312-1-warthog618@gmail.com>
Add support for GPIO_V2_LINE_SET_CONFIG_IOCTL, the uAPI v2
line set config ioctl.
Signed-off-by: Kent Gibson <warthog618@gmail.com>
---
drivers/gpio/gpiolib-cdev.c | 92 +++++++++++++++++++++++++++++++++++++
1 file changed, 92 insertions(+)
diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c
index c1b916224240..d34dad50a048 100644
--- a/drivers/gpio/gpiolib-cdev.c
+++ b/drivers/gpio/gpiolib-cdev.c
@@ -16,6 +16,7 @@
#include <linux/kernel.h>
#include <linux/kfifo.h>
#include <linux/module.h>
+#include <linux/mutex.h>
#include <linux/pinctrl/consumer.h>
#include <linux/poll.h>
#include <linux/spinlock.h>
@@ -418,6 +419,8 @@ struct edge_detector {
* @seqno: the sequence number for edge events generated on all lines in
* this line request. Note that this is not used when @num_descs is 1, as
* the line_seqno is then the same and is cheaper to calculate.
+ * @config_mutex: mutex for serializing ioctl() calls to ensure consistency
+ * of configuration, particularly multi-step accesses to desc flags.
* @edets: an array of edge detectors, of size @num_descs
* @descs: the GPIO descriptors held by this line request, with @num_descs
* elements.
@@ -429,6 +432,7 @@ struct line {
wait_queue_head_t wait;
DECLARE_KFIFO_PTR(events, struct gpio_v2_line_event);
atomic_t seqno;
+ struct mutex config_mutex;
struct edge_detector *edets;
struct gpio_desc *descs[];
};
@@ -703,6 +707,30 @@ static int gpio_v2_line_config_validate(struct gpio_v2_line_config *lc,
return 0;
}
+static int gpio_v2_line_config_change_validate(struct line *line,
+ struct gpio_v2_line_config *lc)
+{
+ int i;
+ u64 flags;
+ struct gpio_desc *desc;
+
+ for (i = 0; i < line->num_descs; i++) {
+ desc = line->descs[i];
+ flags = gpio_v2_line_config_flags(lc, i);
+ /* disallow edge detection changes */
+ if (line->edets[i].flags != (flags & GPIO_V2_LINE_EDGE_FLAGS))
+ return -EINVAL;
+
+ if (line->edets[i].flags) {
+ /* disallow polarity changes */
+ if (test_bit(FLAG_ACTIVE_LOW, &desc->flags) !=
+ ((flags & GPIO_V2_LINE_FLAG_ACTIVE_LOW) != 0))
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+
static void gpio_v2_line_config_flags_to_desc_flags(u64 flags,
unsigned long *flagsp)
{
@@ -783,6 +811,67 @@ static long line_get_values(struct line *line, void __user *ip)
return 0;
}
+static long line_set_config_locked(struct line *line,
+ struct gpio_v2_line_config *lc)
+{
+ struct gpio_desc *desc;
+ int i, ret;
+ u64 flags;
+
+ ret = gpio_v2_line_config_change_validate(line, lc);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < line->num_descs; i++) {
+ desc = line->descs[i];
+ flags = gpio_v2_line_config_flags(lc, i);
+
+ gpio_v2_line_config_flags_to_desc_flags(flags, &desc->flags);
+ /*
+ * Lines have to be requested explicitly for input
+ * or output, else the line will be treated "as is".
+ */
+ if (flags & GPIO_V2_LINE_FLAG_OUTPUT) {
+ int val = gpio_v2_line_config_output_value(lc, i);
+
+ edge_detector_stop(&line->edets[i]);
+ ret = gpiod_direction_output(desc, val);
+ if (ret)
+ return ret;
+ } else if (flags & GPIO_V2_LINE_FLAG_INPUT) {
+ ret = gpiod_direction_input(desc);
+ if (ret)
+ return ret;
+ }
+
+ blocking_notifier_call_chain(&desc->gdev->notifier,
+ GPIO_V2_LINE_CHANGED_CONFIG,
+ desc);
+ }
+ return 0;
+}
+
+static long line_set_config(struct line *line, void __user *ip)
+{
+ struct gpio_v2_line_config lc;
+ int ret;
+
+ if (copy_from_user(&lc, ip, sizeof(lc)))
+ return -EFAULT;
+
+ ret = gpio_v2_line_config_validate(&lc, line->num_descs);
+ if (ret)
+ return ret;
+
+ mutex_lock(&line->config_mutex);
+
+ ret = line_set_config_locked(line, &lc);
+
+ mutex_unlock(&line->config_mutex);
+
+ return ret;
+}
+
static long line_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
@@ -791,6 +880,8 @@ static long line_ioctl(struct file *file, unsigned int cmd,
if (cmd == GPIO_V2_LINE_GET_VALUES_IOCTL)
return line_get_values(line, ip);
+ else if (cmd == GPIO_V2_LINE_SET_CONFIG_IOCTL)
+ return line_set_config(line, ip);
return -EINVAL;
}
@@ -964,6 +1055,7 @@ static int line_create(struct gpio_device *gdev, void __user *ip)
}
}
+ mutex_init(&line->config_mutex);
init_waitqueue_head(&line->wait);
if (has_edge_detection) {
size = lr.event_buffer_size;
--
2.28.0
next prev parent reply other threads:[~2020-08-09 13:26 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-08-09 13:25 [PATCH v3 00/18] gpio: cdev: add uAPI v2 Kent Gibson
2020-08-09 13:25 ` [PATCH v3 01/18] gpio: uapi: define GPIO_MAX_NAME_SIZE for array sizes Kent Gibson
2020-08-09 13:25 ` [PATCH v3 02/18] gpio: uapi: define uAPI v2 Kent Gibson
2020-08-11 19:11 ` Bartosz Golaszewski
2020-08-12 1:54 ` Kent Gibson
2020-08-12 17:48 ` Bartosz Golaszewski
2020-08-09 13:25 ` [PATCH v3 03/18] gpiolib: make cdev a build option Kent Gibson
2020-08-09 13:25 ` [PATCH v3 04/18] gpiolib: add build option for CDEV v1 ABI Kent Gibson
2020-08-09 13:25 ` [PATCH v3 05/18] gpiolib: cdev: support GPIO_V2_GET_LINE_IOCTL and GPIO_V2_LINE_GET_VALUES_IOCTL Kent Gibson
2020-08-11 1:56 ` Kent Gibson
2020-08-09 13:25 ` [PATCH v3 06/18] gpiolib: cdev: support GPIO_V2_GET_LINEINFO_IOCTL and GPIO_V2_GET_LINEINFO_WATCH_IOCTL Kent Gibson
2020-08-12 5:29 ` Kent Gibson
2020-08-09 13:25 ` [PATCH v3 07/18] gpiolib: cdev: support edge detection for uAPI v2 Kent Gibson
2020-08-09 13:25 ` Kent Gibson [this message]
2020-08-09 13:25 ` [PATCH v3 09/18] gpiolib: cdev: support GPIO_V2_LINE_SET_VALUES_IOCTL Kent Gibson
2020-08-09 13:25 ` [PATCH v3 10/18] gpiolib: cdev: support setting debounce Kent Gibson
2020-08-09 13:25 ` [PATCH v3 11/18] gpio: uapi: document uAPI v1 as deprecated Kent Gibson
2020-08-09 13:25 ` [PATCH v3 12/18] tools: gpio: port lsgpio to v2 uAPI Kent Gibson
2020-08-09 13:25 ` [PATCH v3 13/18] tools: gpio: port gpio-watch " Kent Gibson
2020-08-09 13:25 ` [PATCH v3 14/18] tools: gpio: rename nlines to num_lines Kent Gibson
2020-08-09 13:25 ` [PATCH v3 15/18] tools: gpio: port gpio-hammer to v2 uAPI Kent Gibson
2020-08-09 13:25 ` [PATCH v3 16/18] tools: gpio: port gpio-event-mon " Kent Gibson
2020-08-09 13:25 ` [PATCH v3 17/18] tools: gpio: add multi-line monitoring to gpio-event-mon Kent Gibson
2020-08-09 13:25 ` [PATCH v3 18/18] tools: gpio: add debounce support " Kent Gibson
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=20200809132529.264312-9-warthog618@gmail.com \
--to=warthog618@gmail.com \
--cc=bgolaszewski@baylibre.com \
--cc=linus.walleij@linaro.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
/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.