From patchwork Fri Nov 27 21:36:12 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Rosin X-Patchwork-Id: 7715351 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id DAF5CBEEE1 for ; Fri, 27 Nov 2015 21:39:03 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 043FD20658 for ; Fri, 27 Nov 2015 21:39:03 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 0B906205B3 for ; Fri, 27 Nov 2015 21:39:02 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1a2Qhd-0008Tt-Va; Fri, 27 Nov 2015 21:37:13 +0000 Received: from mail.lysator.liu.se ([2001:6b0:17:f0a0::3]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1a2QhL-0008O3-0u for linux-arm-kernel@lists.infradead.org; Fri, 27 Nov 2015 21:36:56 +0000 Received: from mail.lysator.liu.se (localhost [127.0.0.1]) by mail.lysator.liu.se (Postfix) with ESMTP id 576F440079; Fri, 27 Nov 2015 22:36:29 +0100 (CET) Received: from localhost.localdomain (217-210-101-82-no95.business.telia.com [217.210.101.82]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.lysator.liu.se (Postfix) with ESMTPSA id 9C6064000E; Fri, 27 Nov 2015 22:36:28 +0100 (CET) From: Peter Rosin To: linux-gpio@vger.kernel.org Subject: [RFC PATCH 1/2] gpio: Add isr property of gpio pins Date: Fri, 27 Nov 2015 22:36:12 +0100 Message-Id: <1448660173-29214-2-git-send-email-peda@lysator.liu.se> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1448660173-29214-1-git-send-email-peda@lysator.liu.se> References: <1448660173-29214-1-git-send-email-peda@lysator.liu.se> X-Virus-Scanned: ClamAV using ClamSMTP X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20151127_133655_538314_5AF5D97D X-CRM114-Status: GOOD ( 14.69 ) X-Spam-Score: -4.2 (----) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexandre Courbot , Peter Rosin , Linus Walleij , linux-kernel@vger.kernel.org, Jean-Christophe Plagniol-Villard , Peter Rosin , linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Peter Rosin Adds the possibility to read the interrupt status register bit for the gpio pin. Expose the bit as an isr file in sysfs. Signed-off-by: Peter Rosin --- Documentation/gpio/sysfs.txt | 12 ++++++++++++ drivers/gpio/gpiolib-sysfs.c | 30 ++++++++++++++++++++++++++++++ drivers/gpio/gpiolib.c | 15 +++++++++++++++ include/linux/gpio/consumer.h | 1 + include/linux/gpio/driver.h | 2 ++ 5 files changed, 60 insertions(+) diff --git a/Documentation/gpio/sysfs.txt b/Documentation/gpio/sysfs.txt index 535b6a8a7a7c..ded7ef9d01be 100644 --- a/Documentation/gpio/sysfs.txt +++ b/Documentation/gpio/sysfs.txt @@ -97,6 +97,18 @@ and have the following read/write attributes: for "rising" and "falling" edges will follow this setting. + "isr" ... reads as either 0 (false) or 1 (true). Reading the + file will clear the value, so that reading a 1 means + that there has been an interrupt-triggering action + on the pin since the file was last read. + + This file exists only if the gpio chip supports reading + the interrupt status register bit for the pin. + + Note that if reading the isr register for this pin + interferes with active interrupts, the read will fail + with an error. + 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 b57ed8e55ab5..f6fe68fab191 100644 --- a/drivers/gpio/gpiolib-sysfs.c +++ b/drivers/gpio/gpiolib-sysfs.c @@ -139,6 +139,28 @@ static ssize_t value_store(struct device *dev, } static DEVICE_ATTR_RW(value); +static ssize_t isr_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gpiod_data *data = dev_get_drvdata(dev); + struct gpio_desc *desc = data->desc; + ssize_t status; + int isr; + + mutex_lock(&data->mutex); + + isr = gpiod_get_isr_cansleep(desc); + if (isr < 0) + status = isr; + else + status = sprintf(buf, "%d\n", isr); + + mutex_unlock(&data->mutex); + + return status; +} +static DEVICE_ATTR_RO(isr); + static irqreturn_t gpio_sysfs_irq(int irq, void *priv) { struct gpiod_data *data = priv; @@ -367,6 +389,13 @@ static umode_t gpio_is_visible(struct kobject *kobj, struct attribute *attr, mode = 0; if (!show_direction && test_bit(FLAG_IS_OUT, &desc->flags)) mode = 0; + } else if (attr == &dev_attr_isr.attr) { + if (!desc->chip->get_isr) + mode = 0; + if (gpiod_to_irq(desc) < 0) + mode = 0; + if (!show_direction && test_bit(FLAG_IS_OUT, &desc->flags)) + mode = 0; } return mode; @@ -377,6 +406,7 @@ static struct attribute *gpio_attrs[] = { &dev_attr_edge.attr, &dev_attr_value.attr, &dev_attr_active_low.attr, + &dev_attr_isr.attr, NULL, }; diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index bf4bd1d120c3..b45e70b2713e 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1572,6 +1572,21 @@ int gpiod_get_value_cansleep(const struct gpio_desc *desc) } EXPORT_SYMBOL_GPL(gpiod_get_value_cansleep); +int gpiod_get_isr_cansleep(const struct gpio_desc *desc) +{ + struct gpio_chip *chip; + int offset; + + might_sleep_if(extra_checks); + if (!desc) + return -EINVAL; + + chip = desc->chip; + offset = gpio_chip_hwgpio(desc); + return chip->get_isr ? chip->get_isr(chip, offset) : -ENXIO; +} +EXPORT_SYMBOL_GPL(gpiod_get_isr_cansleep); + /** * gpiod_set_raw_value_cansleep() - assign a gpio's raw value * @desc: gpio whose value will be assigned diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h index adac255aee86..d0290c14dc84 100644 --- a/include/linux/gpio/consumer.h +++ b/include/linux/gpio/consumer.h @@ -119,6 +119,7 @@ void gpiod_set_raw_value_cansleep(struct gpio_desc *desc, int value); void gpiod_set_raw_array_value_cansleep(unsigned int array_size, struct gpio_desc **desc_array, int *value_array); +int gpiod_get_isr_cansleep(const struct gpio_desc *desc); int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce); diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index c8393cd4d44f..dccfb12f9112 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -96,6 +96,8 @@ struct gpio_chip { unsigned offset); void (*set)(struct gpio_chip *chip, unsigned offset, int value); + int (*get_isr)(struct gpio_chip *chip, + unsigned offset); void (*set_multiple)(struct gpio_chip *chip, unsigned long *mask, unsigned long *bits);