From patchwork Thu Jan 23 14:05:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 1228023 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bgdev.pl Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=bgdev-pl.20150623.gappssmtp.com header.i=@bgdev-pl.20150623.gappssmtp.com header.a=rsa-sha256 header.s=20150623 header.b=M45+4iAd; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 483PDd5jmhz9sSK for ; Fri, 24 Jan 2020 01:05:21 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727590AbgAWOFU (ORCPT ); Thu, 23 Jan 2020 09:05:20 -0500 Received: from mail-wm1-f66.google.com ([209.85.128.66]:38495 "EHLO mail-wm1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727312AbgAWOFU (ORCPT ); Thu, 23 Jan 2020 09:05:20 -0500 Received: by mail-wm1-f66.google.com with SMTP id u2so2671726wmc.3 for ; Thu, 23 Jan 2020 06:05:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=K3tKF/sG1li0TNgHDm/zaOCBiB+0gN/tDFvNC2uEQ+I=; b=M45+4iAd/+so2uPjQePCigx7UoGTuLYGKSenM9uGxUtckyFOJjElOUJxoiKVrJNRUN 2gqepqxrBfH5dPejaSBDW1yuf5y97jJdD+qt1bvlfxR9hxDBbDQ0zZTH1WzrTU3rm7kV PPI6jmoKG1ailpQ57whCSDVbj3DxT6rDqgUWyxCgtTGSkwoqD+GYsuSCcQbYW9vxJJDP 9lgIGV0XL2WkfNz1r4RKnOHMc2hhAPJ+DyYdyTUf0Hs3tUGgM6uX+GH9/w9Sw2L1B/Br NSN8kXuNplpCzDqggd24rgugepc21nxiILx2PdE/r53zvrT7mNoZpNwNLz39mIsuIXqa rFmQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=K3tKF/sG1li0TNgHDm/zaOCBiB+0gN/tDFvNC2uEQ+I=; b=JC+42l3LIucz6bAcCWrHt32mxhknh/d+5InL54UfKqyr83z+ktb6CWK2v0rLdtHqZ3 7JUuswc7gqqh2IKAcCdMWTVd7cP+SVRC1/JtW8HPm5VwVcxbQv6TqvIgoLw5OgWWFZ6E LVK8wbrerjjNpCo8UkkUKWp1GPwbo7cuKrBGGdu9IC+7JpmUQiWXBnP/TRgt39M8UHTb 7MPxfWtXIUB2dF5yiTOXUc2J+3EWt8svxH15KPBBW3taXcHeuGGoSWSaZsYcmKbB7aW9 qA6cdxXnYEmCcy4T2CX8JOORoKgqdKUewy+0IRPRv2oWx0xodr1sAtoJzLCFvDtxE5np GcMQ== X-Gm-Message-State: APjAAAXRh4LuLI/PtuLW180ZTxET3yj2EC91Qv+tL35uTT1ye5fdNZ/g mbvS30OdKL29gToc+2y1s8HIFQ== X-Google-Smtp-Source: APXvYqzgRoWJ/oQdJZsSS4fRPBaJ7vR9DWyEx17TRO9JFNLK4Ww1iOuMfcttEUdy/2yBNu3UKk8Kng== X-Received: by 2002:a1c:7e0b:: with SMTP id z11mr4472464wmc.88.1579788318282; Thu, 23 Jan 2020 06:05:18 -0800 (PST) Received: from localhost.localdomain (amontpellier-652-1-53-230.w109-210.abo.wanadoo.fr. [109.210.44.230]) by smtp.gmail.com with ESMTPSA id n16sm3100963wro.88.2020.01.23.06.05.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 23 Jan 2020 06:05:17 -0800 (PST) From: Bartosz Golaszewski To: Kent Gibson , Linus Walleij , Andy Shevchenko , Greg Kroah-Hartman , Andrew Morton , Jiri Kosina , Stefani Seibold Cc: linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, Bartosz Golaszewski Subject: [RESEND PATCH v5 1/7] kfifo: provide noirqsave variants of spinlocked in and out helpers Date: Thu, 23 Jan 2020 15:05:00 +0100 Message-Id: <20200123140506.29275-2-brgl@bgdev.pl> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20200123140506.29275-1-brgl@bgdev.pl> References: <20200123140506.29275-1-brgl@bgdev.pl> MIME-Version: 1.0 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Bartosz Golaszewski Provide variants of spinlocked kfifo_in() and kfifo_out() routines which don't disable interrupts. Signed-off-by: Bartosz Golaszewski --- include/linux/kfifo.h | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h index fc4b0b10210f..123c200ed7cb 100644 --- a/include/linux/kfifo.h +++ b/include/linux/kfifo.h @@ -517,6 +517,26 @@ __kfifo_uint_must_check_helper( \ __ret; \ }) +/** + * kfifo_in_spinlocked_noirqsave - put data into fifo using a spinlock for + * locking, don't disable interrupts + * @fifo: address of the fifo to be used + * @buf: the data to be added + * @n: number of elements to be added + * @lock: pointer to the spinlock to use for locking + * + * This is a variant of kfifo_in_spinlocked() but uses spin_lock/unlock() + * for locking and doesn't disable interrupts. + */ +#define kfifo_in_spinlocked_noirqsave(fifo, buf, n, lock) \ +({ \ + unsigned int __ret; \ + spin_lock(lock); \ + __ret = kfifo_in(fifo, buf, n); \ + spin_unlock(lock); \ + __ret; \ +}) + /* alias for kfifo_in_spinlocked, will be removed in a future release */ #define kfifo_in_locked(fifo, buf, n, lock) \ kfifo_in_spinlocked(fifo, buf, n, lock) @@ -569,6 +589,28 @@ __kfifo_uint_must_check_helper( \ }) \ ) +/** + * kfifo_out_spinlocked_noirqsave - get data from the fifo using a spinlock + * for locking, don't disable interrupts + * @fifo: address of the fifo to be used + * @buf: pointer to the storage buffer + * @n: max. number of elements to get + * @lock: pointer to the spinlock to use for locking + * + * This is a variant of kfifo_out_spinlocked() which uses spin_lock/unlock() + * for locking and doesn't disable interrupts. + */ +#define kfifo_out_spinlocked_noirqsave(fifo, buf, n, lock) \ +__kfifo_uint_must_check_helper( \ +({ \ + unsigned int __ret; \ + spin_lock(lock); \ + __ret = kfifo_out(fifo, buf, n); \ + spin_unlock(lock); \ + __ret; \ +}) \ +) + /* alias for kfifo_out_spinlocked, will be removed in a future release */ #define kfifo_out_locked(fifo, buf, n, lock) \ kfifo_out_spinlocked(fifo, buf, n, lock) From patchwork Thu Jan 23 14:05:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 1228030 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bgdev.pl Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=bgdev-pl.20150623.gappssmtp.com header.i=@bgdev-pl.20150623.gappssmtp.com header.a=rsa-sha256 header.s=20150623 header.b=fEJGbr7M; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 483PFM524dz9sSZ for ; Fri, 24 Jan 2020 01:05:59 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729019AbgAWOFY (ORCPT ); Thu, 23 Jan 2020 09:05:24 -0500 Received: from mail-wm1-f68.google.com ([209.85.128.68]:53976 "EHLO mail-wm1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727312AbgAWOFV (ORCPT ); Thu, 23 Jan 2020 09:05:21 -0500 Received: by mail-wm1-f68.google.com with SMTP id m24so2693795wmc.3 for ; Thu, 23 Jan 2020 06:05:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=3GsK7s8K6DIS0JIxs6gZ15L0MgMAbrzcUa2gzsoGKiM=; b=fEJGbr7MJ2EjCq8HYkTsAyu2k193Bh3jN0H0bWKRYgQY33vr77MxUHpfIODJrnglMF oI3SOf7bOKkbx0eR8VJCdySsymi7DOJ7E+9HhzE1AO9CEhpyj5iyUE7POae1ZPKuXlT9 6XJIEW07yGsohy1VMKB+SMIvGCWvJsCC+fjx6LfVbz+Z8JtgJVSPFMGXMfEVdrj0IeVU 29f1sltrz4AtOLNqusPPcgPdm22GCK/TrLRikk3PRlPjWAkFp1o8TRV3N48DGV06lUEK qAZseBeZxZnbkNv4Ch6eV9dqE7M+eZ9jPY+kLLtADkT6QU6VYysvFB0lv4kBEZUraxMo 3luQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=3GsK7s8K6DIS0JIxs6gZ15L0MgMAbrzcUa2gzsoGKiM=; b=Fi1vbB3su97DXYG5z70hZTn6VDvzz4b6mEDhKg4BaCfMpFwdFlqjv28jeV2a0JnCr6 NsuMqETE2Ott4JD7ytSe92FvqVuTXWMIQNkuC/R4qSP9SF3w4CoOjWe2/SCRr270vxRM ETxVsjKNl3nx+5k/uEZIeAi3BOUcDlCoTGiASo05YV7xFeEb7hnTLIuXjgize7udXiPr yE6nCYpVNhmaOvEwEw9S8cl8BkIoqOVdUHKHwQalDuMYXxQb/vCAAnFsLCB3dAc0IpOR 0TLnov9XKG11CxyPvSwB6q3sj9J/8pH/4T0R4ciefP7xTtFeyrCQRYHmITzSVCFrFx59 vT7A== X-Gm-Message-State: APjAAAWNve+QU1kwOJ54CNmnkpRp8l0B76tb39WX+iDnZ9Kh9DLtqYkO VltGMcHDjvvYws3r9wkzlsf7eg== X-Google-Smtp-Source: APXvYqwl1Nv4aSf47ULiMfgkeOFZuih3o0I+acG52VBTsjkpi9ZAZ6Z3zKQBHkYANXNvBH6gVbWZEA== X-Received: by 2002:a1c:964f:: with SMTP id y76mr4326006wmd.62.1579788319801; Thu, 23 Jan 2020 06:05:19 -0800 (PST) Received: from localhost.localdomain (amontpellier-652-1-53-230.w109-210.abo.wanadoo.fr. [109.210.44.230]) by smtp.gmail.com with ESMTPSA id n16sm3100963wro.88.2020.01.23.06.05.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 23 Jan 2020 06:05:19 -0800 (PST) From: Bartosz Golaszewski To: Kent Gibson , Linus Walleij , Andy Shevchenko , Greg Kroah-Hartman , Andrew Morton , Jiri Kosina , Stefani Seibold Cc: linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, Bartosz Golaszewski Subject: [RESEND PATCH v5 2/7] kfifo: provide kfifo_is_empty_spinlocked() Date: Thu, 23 Jan 2020 15:05:01 +0100 Message-Id: <20200123140506.29275-3-brgl@bgdev.pl> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20200123140506.29275-1-brgl@bgdev.pl> References: <20200123140506.29275-1-brgl@bgdev.pl> MIME-Version: 1.0 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Bartosz Golaszewski Provide two spinlocked versions of kfifo_is_empty() to be used with spinlocked variants of kfifo_in() and kfifo_out(). Signed-off-by: Bartosz Golaszewski --- include/linux/kfifo.h | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h index 123c200ed7cb..86249476b57f 100644 --- a/include/linux/kfifo.h +++ b/include/linux/kfifo.h @@ -246,6 +246,37 @@ __kfifo_int_must_check_helper(int val) __tmpq->kfifo.in == __tmpq->kfifo.out; \ }) +/** + * kfifo_is_empty_spinlocked - returns true if the fifo is empty using + * a spinlock for locking + * @fifo: address of the fifo to be used + * @lock: spinlock to be used for locking + */ +#define kfifo_is_empty_spinlocked(fifo, lock) \ +({ \ + unsigned long __flags; \ + bool __ret; \ + spin_lock_irqsave(lock, __flags); \ + __ret = kfifo_is_empty(fifo); \ + spin_unlock_irqrestore(lock, __flags); \ + __ret; \ +}) + +/** + * kfifo_is_empty_spinlocked_noirqsave - returns true if the fifo is empty + * using a spinlock for locking, doesn't disable interrupts + * @fifo: address of the fifo to be used + * @lock: spinlock to be used for locking + */ +#define kfifo_is_empty_spinlocked_noirqsave(fifo, lock) \ +({ \ + bool __ret; \ + spin_lock(lock); \ + __ret = kfifo_is_empty(fifo); \ + spin_unlock(lock); \ + __ret; \ +}) + /** * kfifo_is_full - returns true if the fifo is full * @fifo: address of the fifo to be used From patchwork Thu Jan 23 14:05:02 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 1228024 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bgdev.pl Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=bgdev-pl.20150623.gappssmtp.com header.i=@bgdev-pl.20150623.gappssmtp.com header.a=rsa-sha256 header.s=20150623 header.b=FIVul6Zd; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 483PDh1z3Lz9sSN for ; Fri, 24 Jan 2020 01:05:24 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729027AbgAWOFX (ORCPT ); Thu, 23 Jan 2020 09:05:23 -0500 Received: from mail-wr1-f67.google.com ([209.85.221.67]:38536 "EHLO mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729019AbgAWOFX (ORCPT ); Thu, 23 Jan 2020 09:05:23 -0500 Received: by mail-wr1-f67.google.com with SMTP id y17so3211095wrh.5 for ; Thu, 23 Jan 2020 06:05:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=FA3+2VP5jAU36J2OH+8r6uyx7DpqKu5B6mxuwntNrmg=; b=FIVul6Zd+MNkxAiTxs++rOJKqntnVHvPkSrr9SPlCjSCyzSBN0oMG1jz/DL7XUj4r/ 7CPWa1FCEoyceL+0spyCWLq11Mucppuo1lIXJT1eZwE5OFs76f6r6Gl3kngGifwvgolZ UeKIaLY7lznV3fssDN2vC7NyLD8RxnerrtnjN+5MRatJolfO+rVrkOukrzdO4+ryc8WX O5t52xKkmisT253l5w2mgtG8ydsoq3ZOKGoTE+3NkV9OvP8iBPzCtZOs4hSyzXfVwQJP YJxhS6hiewU7fWeKnNsfKt026uAvOeFAaL9w04b8APCZsV8r8jGjg3CD41m8h0wG7Jjr qaAQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=FA3+2VP5jAU36J2OH+8r6uyx7DpqKu5B6mxuwntNrmg=; b=DDCFS9QL2Adwl6M21vtiWEUvWr4ok8Uh4zXV5spWyv7hxFG8dOD+bsfO/X1e57SvYz vXpKUOwVHELxvPRE2pKL2u5tRRGFK+gTzbjabihYJRgWRTjRegaumzYcjOaa8L+yXiI5 fe8rWZ1GG4RQ0AtDWfBsh/epycZEYK0dZqp7k4HBefy3WOdZdVS5FshwmwF2pk3X82DM tWBs0QntUvMz+B4aEGiMoACKj4pxHRvIGWE2thuAqXbEbhsEHpaTKEc09ZnYaR2dvx+b QVrHFP3ORdFoh/WF7gZRidBHquJmvXmBRO0diwPHA5oVg51zrzh4aEP646vTrsE0ChzH oHXQ== X-Gm-Message-State: APjAAAVdFh2g2uBs0ui0hlimm1f8KnZz2I715VklDrhlR7ditBbmSMj4 2+c3vLqmcnthV1/+OLIfoOQq3Owq2fM= X-Google-Smtp-Source: APXvYqxulE3xpxE9DN/jW0xowBaA7wVsGKHEltN2Zo1gOg50igEQN2q2Bh93yGoQWYFH3O/dsKeM3Q== X-Received: by 2002:adf:de84:: with SMTP id w4mr16788681wrl.97.1579788321060; Thu, 23 Jan 2020 06:05:21 -0800 (PST) Received: from localhost.localdomain (amontpellier-652-1-53-230.w109-210.abo.wanadoo.fr. [109.210.44.230]) by smtp.gmail.com with ESMTPSA id n16sm3100963wro.88.2020.01.23.06.05.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 23 Jan 2020 06:05:20 -0800 (PST) From: Bartosz Golaszewski To: Kent Gibson , Linus Walleij , Andy Shevchenko , Greg Kroah-Hartman , Andrew Morton , Jiri Kosina , Stefani Seibold Cc: linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, Bartosz Golaszewski Subject: [RESEND PATCH v5 3/7] gpiolib: rework the locking mechanism for lineevent kfifo Date: Thu, 23 Jan 2020 15:05:02 +0100 Message-Id: <20200123140506.29275-4-brgl@bgdev.pl> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20200123140506.29275-1-brgl@bgdev.pl> References: <20200123140506.29275-1-brgl@bgdev.pl> MIME-Version: 1.0 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Bartosz Golaszewski The read_lock mutex is supposed to prevent collisions between reading and writing to the line event kfifo but it's actually only taken when the events are being read from it. Drop the mutex entirely and reuse the spinlock made available to us in the waitqueue struct. Take the lock whenever the fifo is modified or inspected. Drop the call to kfifo_to_user() and instead first extract the new element from kfifo when the lock is taken and only then pass it on to the user after the spinlock is released. Signed-off-by: Bartosz Golaszewski Reviewed-by: Andy Shevchenko --- drivers/gpio/gpiolib.c | 64 +++++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index ee5ab39d7ab7..43c96e7cdc48 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -796,8 +796,6 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) * @irq: the interrupt that trigger in response to events on this GPIO * @wait: wait queue that handles blocking reads of events * @events: KFIFO for the GPIO events - * @read_lock: mutex lock to protect reads from colliding with adding - * new events to the FIFO * @timestamp: cache for the timestamp storing it between hardirq * and IRQ thread, used to bring the timestamp close to the actual * event @@ -810,7 +808,6 @@ struct lineevent_state { int irq; wait_queue_head_t wait; DECLARE_KFIFO(events, struct gpioevent_data, 16); - struct mutex read_lock; u64 timestamp; }; @@ -826,7 +823,7 @@ static __poll_t lineevent_poll(struct file *filep, poll_wait(filep, &le->wait, wait); - if (!kfifo_is_empty(&le->events)) + if (!kfifo_is_empty_spinlocked_noirqsave(&le->events, &le->wait.lock)) events = EPOLLIN | EPOLLRDNORM; return events; @@ -839,43 +836,52 @@ static ssize_t lineevent_read(struct file *filep, loff_t *f_ps) { struct lineevent_state *le = filep->private_data; - unsigned int copied; + struct gpioevent_data event; + ssize_t bytes_read = 0; int ret; - if (count < sizeof(struct gpioevent_data)) + if (count < sizeof(event)) return -EINVAL; do { + spin_lock(&le->wait.lock); if (kfifo_is_empty(&le->events)) { - if (filep->f_flags & O_NONBLOCK) + if (bytes_read) { + spin_unlock(&le->wait.lock); + return bytes_read; + } + + if (filep->f_flags & O_NONBLOCK) { + spin_unlock(&le->wait.lock); return -EAGAIN; + } - ret = wait_event_interruptible(le->wait, + ret = wait_event_interruptible_locked(le->wait, !kfifo_is_empty(&le->events)); - if (ret) + if (ret) { + spin_unlock(&le->wait.lock); return ret; + } } - if (mutex_lock_interruptible(&le->read_lock)) - return -ERESTARTSYS; - ret = kfifo_to_user(&le->events, buf, count, &copied); - mutex_unlock(&le->read_lock); - - if (ret) - return ret; - - /* - * If we couldn't read anything from the fifo (a different - * thread might have been faster) we either return -EAGAIN if - * the file descriptor is non-blocking, otherwise we go back to - * sleep and wait for more data to arrive. - */ - if (copied == 0 && (filep->f_flags & O_NONBLOCK)) - return -EAGAIN; + ret = kfifo_out(&le->events, &event, 1); + spin_unlock(&le->wait.lock); + if (ret != 1) { + /* + * This should never happen - we were holding the lock + * from the moment we learned the fifo is no longer + * empty until now. + */ + ret = -EIO; + break; + } - } while (copied == 0); + if (copy_to_user(buf + bytes_read, &event, sizeof(event))) + return -EFAULT; + bytes_read += sizeof(event); + } while (count >= bytes_read + sizeof(event)); - return copied; + return bytes_read; } static int lineevent_release(struct inode *inode, struct file *filep) @@ -977,7 +983,8 @@ static irqreturn_t lineevent_irq_thread(int irq, void *p) return IRQ_NONE; } - ret = kfifo_put(&le->events, ge); + ret = kfifo_in_spinlocked_noirqsave(&le->events, &ge, + 1, &le->wait.lock); if (ret) wake_up_poll(&le->wait, EPOLLIN); @@ -1092,7 +1099,6 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip) INIT_KFIFO(le->events); init_waitqueue_head(&le->wait); - mutex_init(&le->read_lock); /* Request a thread to read the events */ ret = request_threaded_irq(le->irq, From patchwork Thu Jan 23 14:05:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 1228029 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bgdev.pl Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=bgdev-pl.20150623.gappssmtp.com header.i=@bgdev-pl.20150623.gappssmtp.com header.a=rsa-sha256 header.s=20150623 header.b=jz7U7Z/a; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 483PFL3z5Bz9sSV for ; Fri, 24 Jan 2020 01:05:58 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729047AbgAWOFY (ORCPT ); Thu, 23 Jan 2020 09:05:24 -0500 Received: from mail-wm1-f67.google.com ([209.85.128.67]:54375 "EHLO mail-wm1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728655AbgAWOFY (ORCPT ); Thu, 23 Jan 2020 09:05:24 -0500 Received: by mail-wm1-f67.google.com with SMTP id b19so2686347wmj.4 for ; Thu, 23 Jan 2020 06:05:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=wytPjSbZC28y5B3ceuqDy/iL3OfZmgStcvzlcuSAif8=; b=jz7U7Z/aYyl8I5OSU0ios0qBeAUM43v1yJBlrTsJeQnJf/BqqPAi504z8WeRVosieu TGl20Q1wWTGKIpZDTmwc4fmX5d98SdZB8vZwyg0MmvLcU7BA21gZuXxDYHglgHcoLn1l 0CsM8wWhJpiToA6HmyXmQJwI7EELoSU/84WzinqKAEfOWi2I0/LiJSVNpEQlzMy4zwcN TRiHuf/TLcWwrEH6Fk/rClK/3nxDXGxmxumZhLWxztZiz6Ewn/5p4zC6fMmO5+w3C6eC c02hEdXgp/XuU7AItL7Hxem/lIHf9MPseyoFE8MY18hggH7+eww5AXB+1G8xX++lRksZ mW4Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=wytPjSbZC28y5B3ceuqDy/iL3OfZmgStcvzlcuSAif8=; b=fVTTkDlrwchCCeY7M2SdpKsZLg7cuvpuUCoxwQRuUfypPuDa61w9wytRYVwT+87s9s KbOmtE97LAhL3zKtTS0b9rvXFdlSTYuH1lCO2Ti22eSUBFpG7/n8B1Zm2JilgG45pArm frKRR0PxwiUe4rzI9ahlTM9v/kjpbBM9n/2oKZ4jpk7H3LpzVrstJdGBsnMnytEUmLIZ Hrs2M0zthz502Avb1ylxiXp2PvcWHYD7TMEPhds9c9Sunlh+IEwoNGURCiC9ldqn/4zV JlccorWkyueQaaMuKcL0dddac/Zil5veUArtjLvmJX9kL0pG46fvFmbg0oGaDVcR5pkl x2lQ== X-Gm-Message-State: APjAAAVyyDaCAnA5wqpzNvYDv41z7t8L1nYF20IjGZq2Jbn3DpktPr6c mnB4ls0WWN5z12LVYVGnC52OaaMW06o= X-Google-Smtp-Source: APXvYqxKdnB/MOVQ0NHV1aEKZe2TS/5dzPNMUejZk9TvQG1pWykD8vOwwEBFhGAmXaLEmvllCQgrLQ== X-Received: by 2002:a1c:5ac2:: with SMTP id o185mr4381705wmb.179.1579788322758; Thu, 23 Jan 2020 06:05:22 -0800 (PST) Received: from localhost.localdomain (amontpellier-652-1-53-230.w109-210.abo.wanadoo.fr. [109.210.44.230]) by smtp.gmail.com with ESMTPSA id n16sm3100963wro.88.2020.01.23.06.05.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 23 Jan 2020 06:05:22 -0800 (PST) From: Bartosz Golaszewski To: Kent Gibson , Linus Walleij , Andy Shevchenko , Greg Kroah-Hartman , Andrew Morton , Jiri Kosina , Stefani Seibold Cc: linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, Bartosz Golaszewski Subject: [RESEND PATCH v5 4/7] gpiolib: emit a debug message when adding events to a full kfifo Date: Thu, 23 Jan 2020 15:05:03 +0100 Message-Id: <20200123140506.29275-5-brgl@bgdev.pl> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20200123140506.29275-1-brgl@bgdev.pl> References: <20200123140506.29275-1-brgl@bgdev.pl> MIME-Version: 1.0 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Bartosz Golaszewski Currently if the line-event kfifo is full, we just silently drop any new events. Add a ratelimited debug message so that we at least have some trace in the kernel log of event overflow. Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpiolib.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 43c96e7cdc48..6b5d102dfb13 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -987,6 +987,8 @@ static irqreturn_t lineevent_irq_thread(int irq, void *p) 1, &le->wait.lock); if (ret) wake_up_poll(&le->wait, EPOLLIN); + else + pr_debug_ratelimited("event FIFO is full - event dropped\n"); return IRQ_HANDLED; } From patchwork Thu Jan 23 14:05:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 1228025 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bgdev.pl Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=bgdev-pl.20150623.gappssmtp.com header.i=@bgdev-pl.20150623.gappssmtp.com header.a=rsa-sha256 header.s=20150623 header.b=amcsvvrs; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 483PDm38Lwz9sSN for ; Fri, 24 Jan 2020 01:05:28 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729078AbgAWOF1 (ORCPT ); Thu, 23 Jan 2020 09:05:27 -0500 Received: from mail-wm1-f67.google.com ([209.85.128.67]:40343 "EHLO mail-wm1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729300AbgAWOF0 (ORCPT ); Thu, 23 Jan 2020 09:05:26 -0500 Received: by mail-wm1-f67.google.com with SMTP id t14so2654276wmi.5 for ; Thu, 23 Jan 2020 06:05:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=dN7BC78Et1/WtU9AfhINNji0d8Qok1cjKZZH7ozfCDA=; b=amcsvvrsJLbQ4eqVYcjtM8o3XYkcO6fXLapB9BIdRVTnzYHBkYgBEwUiEoOn9Aam+D mN0iTYOOev7psYA058rVaw4MBNdrzBmrFPJjArs6fSnuZLA9sEyrWtmxi9Ug57NsXW6f 1Z9HkZ/quBl/I/hrkIF/sr4uj4k/E/GYLOCi5Obi2V8XqCNTX7qgwJxI7wxrc555B2kz wRzEL9wP+wIREcBvYbgjWhh5cn5J4C5XMe666RY6/QS/wthq4EmCjndxqwUOMIH5Zclj pXYtlHIgrzweGufDYS03jFckbCJJBIkhN8T9/xWXGqFTD2ctg28KzR8QUqzsFBoyY/t3 SSfw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=dN7BC78Et1/WtU9AfhINNji0d8Qok1cjKZZH7ozfCDA=; b=W+EG73AUHMNKH5k4/t4ejBPYQypnnnV5XQkrAc9G8WV2+QAJCvDeF1lKNrTSisZJRT gpUCJspJttOpUc2i8cbEHXIftXN8QtwEHoK/c0z5gXEpfYv07LNIr6LrL2NtErZdGaWB EXaLELpNAc+ipjHs95eALuGZmTXzLQgUTdDZ2AejSRPn30Qhf37eexfytbAMPKumzgkN u2dp2XhHbRnfPCrYBxojb1WutWOA+XSK9TRuN28rWVQ/7Wrk87MsgsPnyBIJzGNvAE+z PLRxrpLI703vMBlqA4eUK0e/6M/5ZJZc8nSqrWBXRRP6mWR+cPQv43BjjkS71lSih5xG J/bg== X-Gm-Message-State: APjAAAW9qxodPPI0fslT1IahQpivGZSIaoQhSXOTxT0Zst1IFKmf9wTM tYaE1SoBR9JpNLPaDFDQ7Rq5GA== X-Google-Smtp-Source: APXvYqyz/+iL0QtpYKXOJl5ozbio7JDMAftUdrhfgFzQJPfNZAxLKT9ZzTewrgd5BsEXwn5dAW/J/A== X-Received: by 2002:a7b:c7c9:: with SMTP id z9mr2776209wmk.175.1579788324573; Thu, 23 Jan 2020 06:05:24 -0800 (PST) Received: from localhost.localdomain (amontpellier-652-1-53-230.w109-210.abo.wanadoo.fr. [109.210.44.230]) by smtp.gmail.com with ESMTPSA id n16sm3100963wro.88.2020.01.23.06.05.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 23 Jan 2020 06:05:23 -0800 (PST) From: Bartosz Golaszewski To: Kent Gibson , Linus Walleij , Andy Shevchenko , Greg Kroah-Hartman , Andrew Morton , Jiri Kosina , Stefani Seibold Cc: linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, Bartosz Golaszewski Subject: [RESEND PATCH v5 5/7] gpiolib: provide a dedicated function for setting lineinfo Date: Thu, 23 Jan 2020 15:05:04 +0100 Message-Id: <20200123140506.29275-6-brgl@bgdev.pl> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20200123140506.29275-1-brgl@bgdev.pl> References: <20200123140506.29275-1-brgl@bgdev.pl> MIME-Version: 1.0 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Bartosz Golaszewski We'll soon be filling out the gpioline_info structure in multiple places. Add a separate function that given a gpio_desc sets all relevant fields. Signed-off-by: Bartosz Golaszewski Reviewed-by: Andy Shevchenko --- drivers/gpio/gpiolib.c | 98 ++++++++++++++++++++++++------------------ 1 file changed, 55 insertions(+), 43 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 6b5d102dfb13..00c1fce3c651 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1156,6 +1156,60 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip) return ret; } +static void gpio_desc_to_lineinfo(struct gpio_desc *desc, + struct gpioline_info *info) +{ + struct gpio_chip *chip = desc->gdev->chip; + unsigned long flags; + + spin_lock_irqsave(&gpio_lock, flags); + + if (desc->name) { + strncpy(info->name, desc->name, sizeof(info->name)); + info->name[sizeof(info->name) - 1] = '\0'; + } else { + info->name[0] = '\0'; + } + + if (desc->label) { + strncpy(info->consumer, desc->label, sizeof(info->consumer)); + info->consumer[sizeof(info->consumer) - 1] = '\0'; + } else { + info->consumer[0] = '\0'; + } + + /* + * Userspace only need to know that the kernel is using this GPIO so + * it can't use it. + */ + info->flags = 0; + if (test_bit(FLAG_REQUESTED, &desc->flags) || + test_bit(FLAG_IS_HOGGED, &desc->flags) || + test_bit(FLAG_USED_AS_IRQ, &desc->flags) || + test_bit(FLAG_EXPORT, &desc->flags) || + test_bit(FLAG_SYSFS, &desc->flags) || + !pinctrl_gpio_can_use_line(chip->base + info->line_offset)) + info->flags |= GPIOLINE_FLAG_KERNEL; + if (test_bit(FLAG_IS_OUT, &desc->flags)) + info->flags |= GPIOLINE_FLAG_IS_OUT; + if (test_bit(FLAG_ACTIVE_LOW, &desc->flags)) + info->flags |= GPIOLINE_FLAG_ACTIVE_LOW; + if (test_bit(FLAG_OPEN_DRAIN, &desc->flags)) + info->flags |= (GPIOLINE_FLAG_OPEN_DRAIN | + GPIOLINE_FLAG_IS_OUT); + if (test_bit(FLAG_OPEN_SOURCE, &desc->flags)) + info->flags |= (GPIOLINE_FLAG_OPEN_SOURCE | + GPIOLINE_FLAG_IS_OUT); + if (test_bit(FLAG_BIAS_DISABLE, &desc->flags)) + info->flags |= GPIOLINE_FLAG_BIAS_DISABLE; + if (test_bit(FLAG_PULL_DOWN, &desc->flags)) + info->flags |= GPIOLINE_FLAG_BIAS_PULL_DOWN; + if (test_bit(FLAG_PULL_UP, &desc->flags)) + info->flags |= GPIOLINE_FLAG_BIAS_PULL_UP; + + spin_unlock_irqrestore(&gpio_lock, flags); +} + /* * gpio_ioctl() - ioctl handler for the GPIO chardev */ @@ -1196,49 +1250,7 @@ static long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (IS_ERR(desc)) return PTR_ERR(desc); - if (desc->name) { - strncpy(lineinfo.name, desc->name, - sizeof(lineinfo.name)); - lineinfo.name[sizeof(lineinfo.name)-1] = '\0'; - } else { - lineinfo.name[0] = '\0'; - } - if (desc->label) { - strncpy(lineinfo.consumer, desc->label, - sizeof(lineinfo.consumer)); - lineinfo.consumer[sizeof(lineinfo.consumer)-1] = '\0'; - } else { - lineinfo.consumer[0] = '\0'; - } - - /* - * Userspace only need to know that the kernel is using - * this GPIO so it can't use it. - */ - lineinfo.flags = 0; - if (test_bit(FLAG_REQUESTED, &desc->flags) || - test_bit(FLAG_IS_HOGGED, &desc->flags) || - test_bit(FLAG_USED_AS_IRQ, &desc->flags) || - test_bit(FLAG_EXPORT, &desc->flags) || - test_bit(FLAG_SYSFS, &desc->flags) || - !pinctrl_gpio_can_use_line(chip->base + lineinfo.line_offset)) - lineinfo.flags |= GPIOLINE_FLAG_KERNEL; - if (test_bit(FLAG_IS_OUT, &desc->flags)) - lineinfo.flags |= GPIOLINE_FLAG_IS_OUT; - if (test_bit(FLAG_ACTIVE_LOW, &desc->flags)) - lineinfo.flags |= GPIOLINE_FLAG_ACTIVE_LOW; - if (test_bit(FLAG_OPEN_DRAIN, &desc->flags)) - lineinfo.flags |= (GPIOLINE_FLAG_OPEN_DRAIN | - GPIOLINE_FLAG_IS_OUT); - if (test_bit(FLAG_OPEN_SOURCE, &desc->flags)) - lineinfo.flags |= (GPIOLINE_FLAG_OPEN_SOURCE | - GPIOLINE_FLAG_IS_OUT); - if (test_bit(FLAG_BIAS_DISABLE, &desc->flags)) - lineinfo.flags |= GPIOLINE_FLAG_BIAS_DISABLE; - if (test_bit(FLAG_PULL_DOWN, &desc->flags)) - lineinfo.flags |= GPIOLINE_FLAG_BIAS_PULL_DOWN; - if (test_bit(FLAG_PULL_UP, &desc->flags)) - lineinfo.flags |= GPIOLINE_FLAG_BIAS_PULL_UP; + gpio_desc_to_lineinfo(desc, &lineinfo); if (copy_to_user(ip, &lineinfo, sizeof(lineinfo))) return -EFAULT; From patchwork Thu Jan 23 14:05:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 1228028 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bgdev.pl Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=bgdev-pl.20150623.gappssmtp.com header.i=@bgdev-pl.20150623.gappssmtp.com header.a=rsa-sha256 header.s=20150623 header.b=aB3QufVw; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 483PDx3fYzz9sSN for ; Fri, 24 Jan 2020 01:05:37 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728913AbgAWOFg (ORCPT ); Thu, 23 Jan 2020 09:05:36 -0500 Received: from mail-wm1-f67.google.com ([209.85.128.67]:54391 "EHLO mail-wm1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729317AbgAWOFa (ORCPT ); Thu, 23 Jan 2020 09:05:30 -0500 Received: by mail-wm1-f67.google.com with SMTP id b19so2686700wmj.4 for ; Thu, 23 Jan 2020 06:05:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ZU8xpfGCJYQ2oLL/99Zcc/U08gwl6OsAoQURuK+eP5w=; b=aB3QufVwmZRyVDYA+RE+9v3uf2j7Jeeu9z9hMnyiq3lbxRyY5fut6iCHuiRyd3CaBB h/zuQyhycKaXE1NEOjKAFg/I7NWxXz/jSZQ37mxnsTQPMmfTDfMyCnBh3lyFSAV0PHy2 CcS3t9pOPYP0XlIUuD++RjZzhdiN2c65/FX0NMW4TD/Ek9SS4wwGCZK+sh8b5gGeArAx XPiSpCUPZC1PJC/xjwF3uBsRDcs8NMQDtoU2FgPF/EaxxroNP+fZm5EZRJU7kgDLlYQz xR9YqMiiNMsXfIrwm4eQt1UVaDBzn38EkutHgGuN/mt0j+XTDb28QrhYX7sKngz8tvgF tAFA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ZU8xpfGCJYQ2oLL/99Zcc/U08gwl6OsAoQURuK+eP5w=; b=tXaWEWc9bcp/5f9w7PwccdcKxCsqaU1gBu+0i0AawyHwX7grVd4KS4yK+1TcJ3zFcf kY06Chpwneiar/lWlbBCsn+8Q8CAyJ2DECjJ0EVLbD20SOPgc6UWcNXPfAGoocMaFdjv tkcrrGPPxPCdcty+/ZDXboCRmx40tbgHeqsh3hpeE5AoEMPvGnfxbRtkNtJsOTdWLFaQ SEjL7qSVdXsfcAnFiFg4QmVy3hpo3+T1hXlV6JVq4Eb1cbrOfjjzvhXku8ZPOBKa9Z3m W4FQD/dnwb6ZwEw/xibRQo9Z2/XtbfoqhqCFkFRrRs2HHUN8wvi0h95vIm/RYHbsP1tA HaJQ== X-Gm-Message-State: APjAAAVzuYzyBzvHzDLRndr8WOo/hsS+UG/nkMveueLGpPH/hZuGtLl7 X7cQhR3fBYgj+nCNzs+U/E4XCQ== X-Google-Smtp-Source: APXvYqy7SMJckw1wnquSIQF+NG2A2CHlQGjKZcZb7EZLR5sgkyLQOfeU0cWGc4VQyv+woWf1d/K0yQ== X-Received: by 2002:a1c:7901:: with SMTP id l1mr4348824wme.67.1579788325899; Thu, 23 Jan 2020 06:05:25 -0800 (PST) Received: from localhost.localdomain (amontpellier-652-1-53-230.w109-210.abo.wanadoo.fr. [109.210.44.230]) by smtp.gmail.com with ESMTPSA id n16sm3100963wro.88.2020.01.23.06.05.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 23 Jan 2020 06:05:25 -0800 (PST) From: Bartosz Golaszewski To: Kent Gibson , Linus Walleij , Andy Shevchenko , Greg Kroah-Hartman , Andrew Morton , Jiri Kosina , Stefani Seibold Cc: linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, Bartosz Golaszewski Subject: [RESEND PATCH v5 6/7] gpiolib: add new ioctl() for monitoring changes in line info Date: Thu, 23 Jan 2020 15:05:05 +0100 Message-Id: <20200123140506.29275-7-brgl@bgdev.pl> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20200123140506.29275-1-brgl@bgdev.pl> References: <20200123140506.29275-1-brgl@bgdev.pl> MIME-Version: 1.0 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Bartosz Golaszewski Currently there is no way for user-space to be informed about changes in status of GPIO lines e.g. when someone else requests the line or its config changes. We can only periodically re-read the line-info. This is fine for simple one-off user-space tools, but any daemon that provides a centralized access to GPIO chips would benefit hugely from an event driven line info synchronization. This patch adds a new ioctl() that allows user-space processes to reuse the file descriptor associated with the character device for watching any changes in line properties. Every such event contains the updated line information. Currently the events are generated on three types of status changes: when a line is requested, when it's released and when its config is changed. The first two are self-explanatory. For the third one: this will only happen when another user-space process calls the new SET_CONFIG ioctl() as any changes that can happen from within the kernel (i.e. set_transitory() or set_debounce()) are of no interest to user-space. Signed-off-by: Bartosz Golaszewski --- drivers/gpio/gpiolib.c | 187 ++++++++++++++++++++++++++++++++++++-- drivers/gpio/gpiolib.h | 1 + include/uapi/linux/gpio.h | 30 ++++++ 3 files changed, 210 insertions(+), 8 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 00c1fce3c651..72ed84d822bf 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -555,6 +555,9 @@ static long linehandle_set_config(struct linehandle_state *lh, if (ret) return ret; } + + atomic_notifier_call_chain(&desc->gdev->notifier, + GPIOLINE_CHANGED_CONFIG, desc); } return 0; } @@ -1210,14 +1213,25 @@ static void gpio_desc_to_lineinfo(struct gpio_desc *desc, spin_unlock_irqrestore(&gpio_lock, flags); } +struct gpio_chardev_data { + struct gpio_device *gdev; + wait_queue_head_t wait; + DECLARE_KFIFO(events, struct gpioline_info_changed, 32); + struct notifier_block lineinfo_changed_nb; + unsigned long *watched_lines; +}; + /* * gpio_ioctl() - ioctl handler for the GPIO chardev */ static long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { - struct gpio_device *gdev = filp->private_data; + struct gpio_chardev_data *priv = filp->private_data; + struct gpio_device *gdev = priv->gdev; struct gpio_chip *chip = gdev->chip; void __user *ip = (void __user *)arg; + struct gpio_desc *desc; + __u32 offset; /* We fail any subsequent ioctl():s when the chip is gone */ if (!chip) @@ -1239,9 +1253,9 @@ static long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (copy_to_user(ip, &chipinfo, sizeof(chipinfo))) return -EFAULT; return 0; - } else if (cmd == GPIO_GET_LINEINFO_IOCTL) { + } else if (cmd == GPIO_GET_LINEINFO_IOCTL || + cmd == GPIO_GET_LINEINFO_WATCH_IOCTL) { struct gpioline_info lineinfo; - struct gpio_desc *desc; if (copy_from_user(&lineinfo, ip, sizeof(lineinfo))) return -EFAULT; @@ -1254,11 +1268,25 @@ static long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (copy_to_user(ip, &lineinfo, sizeof(lineinfo))) return -EFAULT; + + if (cmd == GPIO_GET_LINEINFO_WATCH_IOCTL) + set_bit(desc_to_gpio(desc), priv->watched_lines); + return 0; } else if (cmd == GPIO_GET_LINEHANDLE_IOCTL) { return linehandle_create(gdev, ip); } else if (cmd == GPIO_GET_LINEEVENT_IOCTL) { return lineevent_create(gdev, ip); + } else if (cmd == GPIO_GET_LINEINFO_UNWATCH_IOCTL) { + if (copy_from_user(&offset, ip, sizeof(offset))) + return -EFAULT; + + desc = gpiochip_get_desc(chip, offset); + if (IS_ERR(desc)) + return PTR_ERR(desc); + + clear_bit(desc_to_gpio(desc), &desc->flags); + return 0; } return -EINVAL; } @@ -1271,6 +1299,102 @@ static long gpio_ioctl_compat(struct file *filp, unsigned int cmd, } #endif +static struct gpio_chardev_data * +to_gpio_chardev_data(struct notifier_block *nb) +{ + return container_of(nb, struct gpio_chardev_data, lineinfo_changed_nb); +} + +static int lineinfo_changed_notify(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct gpio_chardev_data *priv = to_gpio_chardev_data(nb); + struct gpioline_info_changed chg; + struct gpio_desc *desc = data; + int ret; + + if (!test_bit(desc_to_gpio(desc), priv->watched_lines)) + return NOTIFY_DONE; + + memset(&chg, 0, sizeof(chg)); + chg.info.line_offset = gpio_chip_hwgpio(desc); + chg.event_type = action; + chg.timestamp = ktime_get_real_ns(); + gpio_desc_to_lineinfo(desc, &chg.info); + + ret = kfifo_in_spinlocked(&priv->events, &chg, + 1, &priv->wait.lock); + if (ret) + wake_up_poll(&priv->wait, EPOLLIN); + else + pr_debug_ratelimited("lineinfo event FIFO is full - event dropped\n"); + + return NOTIFY_OK; +} + +static __poll_t lineinfo_watch_poll(struct file *filep, + struct poll_table_struct *pollt) +{ + struct gpio_chardev_data *priv = filep->private_data; + __poll_t events = 0; + + poll_wait(filep, &priv->wait, pollt); + + if (!kfifo_is_empty_spinlocked_noirqsave(&priv->events, + &priv->wait.lock)) + events = EPOLLIN | EPOLLRDNORM; + + return events; +} + +static ssize_t lineinfo_watch_read(struct file *filep, char __user *buf, + size_t count, loff_t *off) +{ + struct gpio_chardev_data *priv = filep->private_data; + struct gpioline_info_changed event; + ssize_t bytes_read = 0; + int ret; + + if (count < sizeof(event)) + return -EINVAL; + + do { + spin_lock(&priv->wait.lock); + if (kfifo_is_empty(&priv->events)) { + if (bytes_read) { + spin_unlock(&priv->wait.lock); + return bytes_read; + } + + if (filep->f_flags & O_NONBLOCK) { + spin_unlock(&priv->wait.lock); + return -EAGAIN; + } + + ret = wait_event_interruptible_locked(priv->wait, + !kfifo_is_empty(&priv->events)); + if (ret) { + spin_unlock(&priv->wait.lock); + return ret; + } + } + + ret = kfifo_out(&priv->events, &event, 1); + spin_unlock(&priv->wait.lock); + if (ret != 1) { + ret = -EIO; + break; + /* We should never get here. See lineevent_read(). */ + } + + if (copy_to_user(buf + bytes_read, &event, sizeof(event))) + return -EFAULT; + bytes_read += sizeof(event); + } while (count >= bytes_read + sizeof(event)); + + return bytes_read; +} + /** * gpio_chrdev_open() - open the chardev for ioctl operations * @inode: inode for this chardev @@ -1281,14 +1405,48 @@ static int gpio_chrdev_open(struct inode *inode, struct file *filp) { struct gpio_device *gdev = container_of(inode->i_cdev, struct gpio_device, chrdev); + struct gpio_chardev_data *priv; + int ret = -ENOMEM; /* Fail on open if the backing gpiochip is gone */ if (!gdev->chip) return -ENODEV; + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->watched_lines = bitmap_zalloc(gdev->chip->ngpio, GFP_KERNEL); + if (!priv->watched_lines) + goto out_free_priv; + + init_waitqueue_head(&priv->wait); + INIT_KFIFO(priv->events); + priv->gdev = gdev; + + priv->lineinfo_changed_nb.notifier_call = lineinfo_changed_notify; + ret = atomic_notifier_chain_register(&gdev->notifier, + &priv->lineinfo_changed_nb); + if (ret) + goto out_free_bitmap; + get_device(&gdev->dev); - filp->private_data = gdev; + filp->private_data = priv; - return nonseekable_open(inode, filp); + ret = nonseekable_open(inode, filp); + if (ret) + goto out_unregister_notifier; + + return ret; + +out_unregister_notifier: + atomic_notifier_chain_unregister(&gdev->notifier, + &priv->lineinfo_changed_nb); +out_free_bitmap: + bitmap_free(priv->watched_lines); +out_free_priv: + kfree(priv); + return ret; } /** @@ -1299,17 +1457,23 @@ static int gpio_chrdev_open(struct inode *inode, struct file *filp) */ static int gpio_chrdev_release(struct inode *inode, struct file *filp) { - struct gpio_device *gdev = container_of(inode->i_cdev, - struct gpio_device, chrdev); + struct gpio_chardev_data *priv = filp->private_data; + struct gpio_device *gdev = priv->gdev; + bitmap_free(priv->watched_lines); + atomic_notifier_chain_unregister(&gdev->notifier, + &priv->lineinfo_changed_nb); put_device(&gdev->dev); + kfree(priv); + return 0; } - static const struct file_operations gpio_fileops = { .release = gpio_chrdev_release, .open = gpio_chrdev_open, + .poll = lineinfo_watch_poll, + .read = lineinfo_watch_read, .owner = THIS_MODULE, .llseek = no_llseek, .unlocked_ioctl = gpio_ioctl, @@ -1520,6 +1684,8 @@ int gpiochip_add_data_with_key(struct gpio_chip *chip, void *data, for (i = 0; i < chip->ngpio; i++) gdev->descs[i].gdev = gdev; + ATOMIC_INIT_NOTIFIER_HEAD(&gdev->notifier); + #ifdef CONFIG_PINCTRL INIT_LIST_HEAD(&gdev->pin_ranges); #endif @@ -2859,6 +3025,8 @@ static int gpiod_request_commit(struct gpio_desc *desc, const char *label) } done: spin_unlock_irqrestore(&gpio_lock, flags); + atomic_notifier_call_chain(&desc->gdev->notifier, + GPIOLINE_CHANGED_REQUESTED, desc); return ret; } @@ -2956,6 +3124,9 @@ static bool gpiod_free_commit(struct gpio_desc *desc) } spin_unlock_irqrestore(&gpio_lock, flags); + atomic_notifier_call_chain(&desc->gdev->notifier, + GPIOLINE_CHANGED_RELEASED, desc); + return ret; } diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index a1cbeabadc69..8e3969616cfe 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -54,6 +54,7 @@ struct gpio_device { const char *label; void *data; struct list_head list; + struct atomic_notifier_head notifier; #ifdef CONFIG_PINCTRL /* diff --git a/include/uapi/linux/gpio.h b/include/uapi/linux/gpio.h index 799cf823d493..10183d4d4276 100644 --- a/include/uapi/linux/gpio.h +++ b/include/uapi/linux/gpio.h @@ -59,6 +59,34 @@ struct gpioline_info { /* Maximum number of requested handles */ #define GPIOHANDLES_MAX 64 +/* Possible line status change events */ +enum { + GPIOLINE_CHANGED_REQUESTED = 1, + GPIOLINE_CHANGED_RELEASED, + GPIOLINE_CHANGED_CONFIG, +}; + +/** + * struct gpioline_info_changed - Information about a change in status + * of a GPIO line + * @info: updated line information + * @timestamp: estimate of time of status change occurrence, in nanoseconds + * and GPIOLINE_CHANGED_CONFIG + * @event_type: one of GPIOLINE_CHANGED_REQUESTED, GPIOLINE_CHANGED_RELEASED + * + * Note: struct gpioline_info embedded here has 32-bit alignment on its own, + * but it works fine with 64-bit alignment too. With its 72 byte size, we can + * guarantee there are no implicit holes between it and subsequent members. + * The 5-byte padding at the end makes sure we don't add any implicit padding + * at the end of the structure on 64-bit architectures. + */ +struct gpioline_info_changed { + struct gpioline_info info; + __u64 timestamp; + __u32 event_type; + __u32 padding[5]; /* for future use */ +}; + /* Linerequest flags */ #define GPIOHANDLE_REQUEST_INPUT (1UL << 0) #define GPIOHANDLE_REQUEST_OUTPUT (1UL << 1) @@ -176,6 +204,8 @@ struct gpioevent_data { #define GPIO_GET_CHIPINFO_IOCTL _IOR(0xB4, 0x01, struct gpiochip_info) #define GPIO_GET_LINEINFO_IOCTL _IOWR(0xB4, 0x02, struct gpioline_info) +#define GPIO_GET_LINEINFO_WATCH_IOCTL _IOWR(0xB4, 0x0b, struct gpioline_info) +#define GPIO_GET_LINEINFO_UNWATCH_IOCTL _IOWR(0xB4, 0x0c, __u32) #define GPIO_GET_LINEHANDLE_IOCTL _IOWR(0xB4, 0x03, struct gpiohandle_request) #define GPIO_GET_LINEEVENT_IOCTL _IOWR(0xB4, 0x04, struct gpioevent_request) From patchwork Thu Jan 23 14:05:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 1228027 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bgdev.pl Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=bgdev-pl.20150623.gappssmtp.com header.i=@bgdev-pl.20150623.gappssmtp.com header.a=rsa-sha256 header.s=20150623 header.b=r1NRMv1l; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 483PDp6SW7z9sSN for ; Fri, 24 Jan 2020 01:05:30 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729337AbgAWOF3 (ORCPT ); Thu, 23 Jan 2020 09:05:29 -0500 Received: from mail-wm1-f66.google.com ([209.85.128.66]:36123 "EHLO mail-wm1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728709AbgAWOF2 (ORCPT ); Thu, 23 Jan 2020 09:05:28 -0500 Received: by mail-wm1-f66.google.com with SMTP id p17so2671381wma.1 for ; Thu, 23 Jan 2020 06:05:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=f+1d4FRlTWDoZyLvhcrUylaJhZuzCdWZutZr0QUDHa4=; b=r1NRMv1lKNUj6IIPd0RJFTxopIS/eswVfnEaJavKAox2ii06YHIak9aCdHPu6cTtsT bvnpDO7OgajlnqCU5yZlgkUFyVNXLQEwJIacsNoTESytpcH51+Ov//s/Cad7hASlssRo iDh1AZOFl3EIsaH7CufcexNRY4qK8nYLfddwqjYfmvO8iT+IvZKC1OFTgUdtxYQqNpEH nyU+UlGKrHRW4B7YY/vhTL+8FAnEE5aLRe+2peaaWr6mmhUm3WZaEnIAnbdYQivZeOkh a/Y7+7Q13XAStl7fIZm1BfUDiW2FYkyfeljUEH9GoWavTUj5B/Q/hcf/yD8Yvzvo/HL5 K1Zg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=f+1d4FRlTWDoZyLvhcrUylaJhZuzCdWZutZr0QUDHa4=; b=fft3OEDEkzQvbAr5+Ff3pJpL3X/2UENq6v9Q+nYj69dmmVeipLnSjTEQPhzlAXy+YG DWOamQoZd04ZDQ6U3ATZiGZlT4jonBmyZWJASAxMuDDMT2cd25jUO/A/ToPV9+WUnnmQ +gEnLLKJP5Ix8ndHbuNBJQVmofik/EGvKBB49J3lllxN4XEraRDMtKRLbuFwkW8CTb8/ agT7Qcjcx/iy/BODr3jszFAZ0tk/t0FHTVhvuJ+vVQMAb+rrATyBAadRX1EH6eTWWQjX dDsYRaiSxUP7QrIXRfDmQJrXSyvLmLdSMNIodxQB8AWQXjQfrpH0hphLo0xf9ogoqTjR FFJw== X-Gm-Message-State: APjAAAUiMwDjQ9n8cOrnSawXFwuoU7VkVEOEA4k/+1l18nK8guwJKS4G qQfyO52Ft8Ambnw7hb/8GYRXOA== X-Google-Smtp-Source: APXvYqwxUh0AWe8ZvFn0nwXnPnoUVBG4RrSgfCix+SDmU/rQsuAPI4+12ddYPHPRLeQh9/UYWCGT1A== X-Received: by 2002:a1c:6707:: with SMTP id b7mr4481392wmc.54.1579788327491; Thu, 23 Jan 2020 06:05:27 -0800 (PST) Received: from localhost.localdomain (amontpellier-652-1-53-230.w109-210.abo.wanadoo.fr. [109.210.44.230]) by smtp.gmail.com with ESMTPSA id n16sm3100963wro.88.2020.01.23.06.05.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 23 Jan 2020 06:05:26 -0800 (PST) From: Bartosz Golaszewski To: Kent Gibson , Linus Walleij , Andy Shevchenko , Greg Kroah-Hartman , Andrew Morton , Jiri Kosina , Stefani Seibold Cc: linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, Bartosz Golaszewski Subject: [RESEND PATCH v5 7/7] tools: gpio: implement gpio-watch Date: Thu, 23 Jan 2020 15:05:06 +0100 Message-Id: <20200123140506.29275-8-brgl@bgdev.pl> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20200123140506.29275-1-brgl@bgdev.pl> References: <20200123140506.29275-1-brgl@bgdev.pl> MIME-Version: 1.0 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Bartosz Golaszewski Add a simple program that allows to test the new LINECHANGED_FD ioctl(). Signed-off-by: Bartosz Golaszewski Reviewed-by: Andy Shevchenko --- tools/gpio/.gitignore | 1 + tools/gpio/Build | 1 + tools/gpio/Makefile | 11 ++++- tools/gpio/gpio-watch.c | 99 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 tools/gpio/gpio-watch.c diff --git a/tools/gpio/.gitignore b/tools/gpio/.gitignore index a94c0e83b209..eab36c6d7751 100644 --- a/tools/gpio/.gitignore +++ b/tools/gpio/.gitignore @@ -1,4 +1,5 @@ gpio-event-mon gpio-hammer +gpio-watch lsgpio include/linux/gpio.h diff --git a/tools/gpio/Build b/tools/gpio/Build index 4141f35837db..67c7b7f6a717 100644 --- a/tools/gpio/Build +++ b/tools/gpio/Build @@ -2,3 +2,4 @@ gpio-utils-y += gpio-utils.o lsgpio-y += lsgpio.o gpio-utils.o gpio-hammer-y += gpio-hammer.o gpio-utils.o gpio-event-mon-y += gpio-event-mon.o gpio-utils.o +gpio-watch-y += gpio-watch.o diff --git a/tools/gpio/Makefile b/tools/gpio/Makefile index 6080de58861f..842287e42c83 100644 --- a/tools/gpio/Makefile +++ b/tools/gpio/Makefile @@ -18,7 +18,7 @@ MAKEFLAGS += -r override CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include -ALL_TARGETS := lsgpio gpio-hammer gpio-event-mon +ALL_TARGETS := lsgpio gpio-hammer gpio-event-mon gpio-watch ALL_PROGRAMS := $(patsubst %,$(OUTPUT)%,$(ALL_TARGETS)) all: $(ALL_PROGRAMS) @@ -66,6 +66,15 @@ $(GPIO_EVENT_MON_IN): prepare FORCE $(OUTPUT)gpio-utils-in.o $(OUTPUT)gpio-event-mon: $(GPIO_EVENT_MON_IN) $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ +# +# gpio-watch +# +GPIO_WATCH_IN := $(OUTPUT)gpio-watch-in.o +$(GPIO_WATCH_IN): prepare FORCE + $(Q)$(MAKE) $(build)=gpio-watch +$(OUTPUT)gpio-watch: $(GPIO_WATCH_IN) + $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@ + clean: rm -f $(ALL_PROGRAMS) rm -f $(OUTPUT)include/linux/gpio.h diff --git a/tools/gpio/gpio-watch.c b/tools/gpio/gpio-watch.c new file mode 100644 index 000000000000..5cea24fddfa7 --- /dev/null +++ b/tools/gpio/gpio-watch.c @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * gpio-watch - monitor unrequested lines for property changes using the + * character device + * + * Copyright (C) 2019 BayLibre SAS + * Author: Bartosz Golaszewski + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + struct gpioline_info_changed chg; + struct gpioline_info req; + struct pollfd pfd; + int fd, i, j, ret; + char *event, *end; + ssize_t rd; + + if (argc < 3) + goto err_usage; + + fd = open(argv[1], O_RDWR | O_CLOEXEC); + if (fd < 0) { + perror("unable to open gpiochip"); + return EXIT_FAILURE; + } + + for (i = 0, j = 2; i < argc - 2; i++, j++) { + memset(&req, 0, sizeof(req)); + + req.line_offset = strtoul(argv[j], &end, 0); + if (*end != '\0') + goto err_usage; + + ret = ioctl(fd, GPIO_GET_LINEINFO_WATCH_IOCTL, &req); + if (ret) { + perror("unable to set up line watch"); + return EXIT_FAILURE; + } + } + + pfd.fd = fd; + pfd.events = POLLIN | POLLPRI; + + for (;;) { + ret = poll(&pfd, 1, 5000); + if (ret < 0) { + perror("error polling the linechanged fd"); + return EXIT_FAILURE; + } else if (ret > 0) { + memset(&chg, 0, sizeof(chg)); + rd = read(pfd.fd, &chg, sizeof(chg)); + if (rd < 0 || rd != sizeof(chg)) { + if (rd != sizeof(chg)) + errno = EIO; + + perror("error reading line change event"); + return EXIT_FAILURE; + } + + switch (chg.event_type) { + case GPIOLINE_CHANGED_REQUESTED: + event = "requested"; + break; + case GPIOLINE_CHANGED_RELEASED: + event = "released"; + break; + case GPIOLINE_CHANGED_CONFIG: + event = "config changed"; + break; + default: + fprintf(stderr, + "invalid event type received from the kernel\n"); + return EXIT_FAILURE; + } + + printf("line %u: %s at %llu\n", + chg.info.line_offset, event, chg.timestamp); + } + } + + return 0; + +err_usage: + printf("%s: ...\n", argv[0]); + return EXIT_FAILURE; +}