Received: by 2002:a05:6a10:a0d1:0:0:0:0 with SMTP id j17csp1691104pxa; Sun, 16 Aug 2020 07:41:35 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzsk5Q2IKLvO2XdCzfw5gnJfCXN82QR/DbldobqhwJDTliADuTJji6WCEPFeDPjoxPH0yWW X-Received: by 2002:a17:906:388b:: with SMTP id q11mr11692593ejd.100.1597588895733; Sun, 16 Aug 2020 07:41:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1597588895; cv=none; d=google.com; s=arc-20160816; b=zhVEBbAgaLYoQboAAdvr87I6vT5VAcF/rg48JfUSrB7WvoD2byvSQohTX9IWE3AdSc EA8VCrg2WeA/fkPz9sbFXuH7evetPuTCPgBO4+n898CdjrAmCSYTDjhcYfdPfFZl8vGH 1lpATLVGnzBNZfF5qL213h2Pqnso6F8nbgPakqP1Wm4pfSTGkfeLd56dC+zhb3CVw1fs zYgC88Oig7UcS0yBxw/i4ryaCQ+fvCo5fIsiTYZkl0lHxNVDJ/VylFVSZUJzLAXVoU1w 3dGm9VLQpTWT6G4mtcegj6h4Toaagql3h7VVNeGBj96S46ZG5LnFsiwrefFbfgVft6CY 6Q/g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=4p5hG5/Sei/XlVH2zj6AeBSvaVMbXHhbmDmsLtAkcC0=; b=e1HjqfHR9379D5Pv2JIGqJHD5VAs4ZvnRyrmN3EJ9Sb2wBnpOmF2nFxMEIs2Sty6gc R1Ty4N1rBzASE+5i69z5rD3Dhm7wBL1HPqyxoop3ntv0uAO+a7QJRkHy29Xe4fM063lD zNYqmuExFQtrVoQi8dE4b1255QwSyeM/82zdRhTX46MYWcka3q/u5BeNBpIv4UgVakRm DIHiZnkTtmSm+dqasSuwn4TzsB6gXUSC2sK9jkBM5dA/2tWxLFnJ+AUMwcX6QQYiU9/g u6BdedSyWiu4N9yT+jm3xyXwSg2G1XrR84rNAdamcg8bGeX11u+LebCnnnRIjuxz2WN+ Z2EA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@baylibre-com.20150623.gappssmtp.com header.s=20150623 header.b=TEBqmj38; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id g6si9115614ejr.212.2020.08.16.07.41.10; Sun, 16 Aug 2020 07:41:35 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@baylibre-com.20150623.gappssmtp.com header.s=20150623 header.b=TEBqmj38; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726708AbgHPOkW (ORCPT + 99 others); Sun, 16 Aug 2020 10:40:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58908 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726304AbgHPOkU (ORCPT ); Sun, 16 Aug 2020 10:40:20 -0400 Received: from mail-qk1-x741.google.com (mail-qk1-x741.google.com [IPv6:2607:f8b0:4864:20::741]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B2891C061385 for ; Sun, 16 Aug 2020 07:40:17 -0700 (PDT) Received: by mail-qk1-x741.google.com with SMTP id m7so12788517qki.12 for ; Sun, 16 Aug 2020 07:40:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=4p5hG5/Sei/XlVH2zj6AeBSvaVMbXHhbmDmsLtAkcC0=; b=TEBqmj389cJKLROjNWabxTnj+YFfcMSNpTI9tvBOFnZdQCHwbAf05Gn39b5lAfcvbD wvNmSlb+VGMURLSK1B8bznW1xyXG5VmDf4KkhVQ02q387aWnu7CAF8pSuy2H/DhGPEIx FYRVubzr++9zoKuz2njcR4sYC4GgAjpuvg9XtOpNUhHkl+ixecBFjffGnP0BteMBRumx 7vSOfENsPBpoFp5tW3lQ3o3RDzG0Xwd3qGh1u5BRJIQ+XE7D/X/im2lzWursnIcxyCa/ ffAG2ssQ1yPo1GlDmaoaJNO4lO7MhNXcn/JvQPs55j5kbKPvLyrZH1b1knrDWj2QfF/7 M3mA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=4p5hG5/Sei/XlVH2zj6AeBSvaVMbXHhbmDmsLtAkcC0=; b=bhNjhfyaIE4n2agQiOA4oOxm3Y2tr8TsPK5G1FDCztRyiVjrdrDC/C/6wnSFjTSYHP ibSNvYEIhNR7IS1zH5m5v3MSr+KodUzUVlagGCsFYFyNQEpgBgf+oyMAj1QspAmkVaXa rEXckXovRVMGfg3frgiL2RSNvjBH4urPbAaiznENvLo7IFJcRJbdrYx3PYq3HK7C4GGO OtMycG3nJxgLY80n+/BuBBuj4LEjWQVDKMvMtPJFvGIYq3S2la84Drddg39zU4X6Rrm7 LDG4HsHoriXby4HbYFf97zXmYaWagjJfoUA9indSAr5ISXQno6NVfWmRe4HN5jCRcElJ 1ISA== X-Gm-Message-State: AOAM532nJCsiUGI9AcRg+z830ztbOb+mAfioSnprHbodwc9yzpGDEJeK shTWBYATTp41D7nbkBHbn7up+mt35IOjomn1noK4xQ== X-Received: by 2002:a37:a495:: with SMTP id n143mr9673976qke.330.1597588812631; Sun, 16 Aug 2020 07:40:12 -0700 (PDT) MIME-Version: 1.0 References: <20200814030257.135463-1-warthog618@gmail.com> <20200814030257.135463-11-warthog618@gmail.com> In-Reply-To: <20200814030257.135463-11-warthog618@gmail.com> From: Bartosz Golaszewski Date: Sun, 16 Aug 2020 16:40:01 +0200 Message-ID: Subject: Re: [PATCH v4 10/20] gpiolib: cdev: support GPIO_V2_LINE_SET_CONFIG_IOCTL To: Kent Gibson Cc: LKML , linux-gpio , Linus Walleij Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, Aug 14, 2020 at 5:04 AM Kent Gibson wrote: > > Add support for GPIO_V2_LINE_SET_CONFIG_IOCTL, the uAPI v2 > line set config ioctl. > > Signed-off-by: Kent Gibson > --- > 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 1d42a01f5414..04472c2b6678 100644 > --- a/drivers/gpio/gpiolib-cdev.c > +++ b/drivers/gpio/gpiolib-cdev.c > @@ -16,6 +16,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -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) I think that the general consensus in the kernel is to suffix functions that need to be called with some lock taken outside them with _unlocked (as in: the function is unlocked on its own). Alternatively such routines are prefixed with __ (__line_set_config()) but I know Linus prefers the former. Bart > +{ > + 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 >