From patchwork Sat Sep 8 09:23:14 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Verkuil X-Patchwork-Id: 967583 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) 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=xs4all.nl Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 426pl552HVz9s3Z for ; Sat, 8 Sep 2018 19:23:29 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726381AbeIHOIa (ORCPT ); Sat, 8 Sep 2018 10:08:30 -0400 Received: from lb1-smtp-cloud9.xs4all.net ([194.109.24.22]:54137 "EHLO lb1-smtp-cloud9.xs4all.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726333AbeIHOIa (ORCPT ); Sat, 8 Sep 2018 10:08:30 -0400 Received: from tschai.fritz.box ([212.251.195.8]) by smtp-cloud9.xs4all.net with ESMTPA id yZSZf0zAxMsEFyZSef6TGA; Sat, 08 Sep 2018 11:23:24 +0200 From: Hans Verkuil To: linux-gpio@vger.kernel.org Cc: Linus Walleij , ilina@codeaurora.org, Marc Zyngier , Thomas Gleixner , Hans Verkuil Subject: [PATCHv2 1/6] gpiolib: export gpiochip_irq_reqres/relres() Date: Sat, 8 Sep 2018 11:23:14 +0200 Message-Id: <20180908092319.43900-2-hverkuil@xs4all.nl> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180908092319.43900-1-hverkuil@xs4all.nl> References: <20180908092319.43900-1-hverkuil@xs4all.nl> X-CMAE-Envelope: MS4wfGElnnH825M24O9ln9tYAAVRmfM3xqYBYYwJnFwdq/8aPxeWREHUZvoKEC/oJMCJNFHDf2CDthyqHiWcsFeDUikjrvkq/qC92pflsvRXTZvqDdFpofag MNaKUZk2OD+5h/xWB8zajTiBqrKDhcRvSDHOdIVzC29QBAhcchyK1sNOvevxTL0XtmQnxQ8UhEuAC0X+P/2W5h1ZkBY1xjibl/5JQZj6fb5pXBjgNJKOXDfR b6ssJLB9kNpJKtmk30cweWLxtqHIDAqsbFAmYVl9MgGTG6w7Pxe79pLUaTF8V4hdcjEwwQ4IaDxUNj9n3nGT4pSdbbfw+EE/ksAA5sER4CQT+YUaWB+Xb+ok KGzxs77I Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Hans Verkuil GPIO drivers that do not use GPIOLIB_IRQCHIP can hook these into the irq_request_resource and irq_release_resource callbacks of the irq_chip so they correctly 'get' the module and lock the gpio line for IRQ use. This will simplify driver code. Signed-off-by: Hans Verkuil --- drivers/gpio/gpiolib.c | 55 ++++++++++++++++++++++--------------- include/linux/gpio/driver.h | 2 ++ 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index e8f8a1999393..cbab0e744de0 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1804,39 +1804,26 @@ static const struct irq_domain_ops gpiochip_domain_ops = { .xlate = irq_domain_xlate_twocell, }; -static int gpiochip_irq_reqres(struct irq_data *d) +static int gpiochip_to_irq(struct gpio_chip *chip, unsigned offset) { - struct gpio_chip *chip = irq_data_get_irq_chip_data(d); - int ret; - - if (!try_module_get(chip->gpiodev->owner)) - return -ENODEV; + if (!gpiochip_irqchip_irq_valid(chip, offset)) + return -ENXIO; - ret = gpiochip_lock_as_irq(chip, d->hwirq); - if (ret) { - chip_err(chip, - "unable to lock HW IRQ %lu for IRQ\n", - d->hwirq); - module_put(chip->gpiodev->owner); - return ret; - } - return 0; + return irq_create_mapping(chip->irq.domain, offset); } -static void gpiochip_irq_relres(struct irq_data *d) +static int gpiochip_irq_reqres(struct irq_data *d) { struct gpio_chip *chip = irq_data_get_irq_chip_data(d); - gpiochip_unlock_as_irq(chip, d->hwirq); - module_put(chip->gpiodev->owner); + return gpiochip_reqres_irq(chip, d->hwirq); } -static int gpiochip_to_irq(struct gpio_chip *chip, unsigned offset) +static void gpiochip_irq_relres(struct irq_data *d) { - if (!gpiochip_irqchip_irq_valid(chip, offset)) - return -ENXIO; + struct gpio_chip *chip = irq_data_get_irq_chip_data(d); - return irq_create_mapping(chip->irq.domain, offset); + gpiochip_relres_irq(chip, d->hwirq); } /** @@ -3338,6 +3325,30 @@ bool gpiochip_line_is_irq(struct gpio_chip *chip, unsigned int offset) } EXPORT_SYMBOL_GPL(gpiochip_line_is_irq); +int gpiochip_reqres_irq(struct gpio_chip *chip, unsigned int offset) +{ + int ret; + + if (!try_module_get(chip->gpiodev->owner)) + return -ENODEV; + + ret = gpiochip_lock_as_irq(chip, offset); + if (ret) { + chip_err(chip, "unable to lock HW IRQ %u for IRQ\n", offset); + module_put(chip->gpiodev->owner); + return ret; + } + return 0; +} +EXPORT_SYMBOL_GPL(gpiochip_reqres_irq); + +void gpiochip_relres_irq(struct gpio_chip *chip, unsigned int offset) +{ + gpiochip_unlock_as_irq(chip, offset); + module_put(chip->gpiodev->owner); +} +EXPORT_SYMBOL_GPL(gpiochip_relres_irq); + bool gpiochip_line_is_open_drain(struct gpio_chip *chip, unsigned int offset) { if (offset >= chip->ngpio) diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 0ea328e71ec9..380251955ad1 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -395,6 +395,8 @@ extern struct gpio_chip *gpiochip_find(void *data, int gpiochip_lock_as_irq(struct gpio_chip *chip, unsigned int offset); void gpiochip_unlock_as_irq(struct gpio_chip *chip, unsigned int offset); bool gpiochip_line_is_irq(struct gpio_chip *chip, unsigned int offset); +int gpiochip_reqres_irq(struct gpio_chip *chip, unsigned int offset); +void gpiochip_relres_irq(struct gpio_chip *chip, unsigned int offset); /* Line status inquiry for drivers */ bool gpiochip_line_is_open_drain(struct gpio_chip *chip, unsigned int offset); From patchwork Sat Sep 8 09:23:15 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Verkuil X-Patchwork-Id: 967585 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) 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=xs4all.nl Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 426pl670CZz9s3Z for ; Sat, 8 Sep 2018 19:23:30 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726351AbeIHOIb (ORCPT ); Sat, 8 Sep 2018 10:08:31 -0400 Received: from lb2-smtp-cloud9.xs4all.net ([194.109.24.26]:38273 "EHLO lb2-smtp-cloud9.xs4all.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726341AbeIHOIa (ORCPT ); Sat, 8 Sep 2018 10:08:30 -0400 Received: from tschai.fritz.box ([212.251.195.8]) by smtp-cloud9.xs4all.net with ESMTPA id yZSZf0zAxMsEFyZSef6TGI; Sat, 08 Sep 2018 11:23:24 +0200 From: Hans Verkuil To: linux-gpio@vger.kernel.org Cc: Linus Walleij , ilina@codeaurora.org, Marc Zyngier , Thomas Gleixner , Hans Verkuil Subject: [PATCHv2 2/6] gliolib: set hooks in gpiochip_set_irq_hooks() Date: Sat, 8 Sep 2018 11:23:15 +0200 Message-Id: <20180908092319.43900-3-hverkuil@xs4all.nl> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180908092319.43900-1-hverkuil@xs4all.nl> References: <20180908092319.43900-1-hverkuil@xs4all.nl> X-CMAE-Envelope: MS4wfGElnnH825M24O9ln9tYAAVRmfM3xqYBYYwJnFwdq/8aPxeWREHUZvoKEC/oJMCJNFHDf2CDthyqHiWcsFeDUikjrvkq/qC92pflsvRXTZvqDdFpofag MNaKUZk2OD+5h/xWB8zajTiBqrKDhcRvSDHOdIVzC29QBAhcchyK1sNOvevxTL0XtmQnxQ8UhEuAC0X+P/2W5h1ZkBY1xjibl/5JQZj6fb5pXBjgNJKOXDfR b6ssJLB9kNpJKtmk30cweWLxtqHIDAqsbFAmYVl9MgGTG6w7Pxe79pLUaTF8V4hdcjEwwQ4IaDxUNj9n3nGT4pSdbbfw+EE/ksAA5sER4CQT+YUaWB+Xb+ok KGzxs77I Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Hans Verkuil Centralize setting the irq_request/release_resources callbacks in one function since we'll be adding more callbacks to that. Also fix the removal of the callback overrides: this should only be done if we actually installed our own callback there. Signed-off-by: Hans Verkuil --- drivers/gpio/gpiolib.c | 45 ++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index cbab0e744de0..b17f1142c70b 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1826,6 +1826,17 @@ static void gpiochip_irq_relres(struct irq_data *d) gpiochip_relres_irq(chip, d->hwirq); } +static void gpiochip_set_irq_hooks(struct gpio_chip *gpiochip) +{ + struct irq_chip *irqchip = gpiochip->irq.chip; + + if (!irqchip->irq_request_resources && + !irqchip->irq_release_resources) { + irqchip->irq_request_resources = gpiochip_irq_reqres; + irqchip->irq_release_resources = gpiochip_irq_relres; + } +} + /** * gpiochip_add_irqchip() - adds an IRQ chip to a GPIO chip * @gpiochip: the GPIO chip to add the IRQ chip to @@ -1884,16 +1895,6 @@ static int gpiochip_add_irqchip(struct gpio_chip *gpiochip, if (!gpiochip->irq.domain) return -EINVAL; - /* - * It is possible for a driver to override this, but only if the - * alternative functions are both implemented. - */ - if (!irqchip->irq_request_resources && - !irqchip->irq_release_resources) { - irqchip->irq_request_resources = gpiochip_irq_reqres; - irqchip->irq_release_resources = gpiochip_irq_relres; - } - if (gpiochip->irq.parent_handler) { void *data = gpiochip->irq.parent_handler_data ?: gpiochip; @@ -1909,6 +1910,8 @@ static int gpiochip_add_irqchip(struct gpio_chip *gpiochip, } } + gpiochip_set_irq_hooks(gpiochip); + acpi_gpiochip_request_interrupts(gpiochip); return 0; @@ -1922,11 +1925,12 @@ static int gpiochip_add_irqchip(struct gpio_chip *gpiochip, */ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip) { + struct irq_chip *irqchip = gpiochip->irq.chip; unsigned int offset; acpi_gpiochip_free_interrupts(gpiochip); - if (gpiochip->irq.chip && gpiochip->irq.parent_handler) { + if (irqchip && gpiochip->irq.parent_handler) { struct gpio_irq_chip *irq = &gpiochip->irq; unsigned int i; @@ -1950,11 +1954,12 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip) irq_domain_remove(gpiochip->irq.domain); } - if (gpiochip->irq.chip) { - gpiochip->irq.chip->irq_request_resources = NULL; - gpiochip->irq.chip->irq_release_resources = NULL; - gpiochip->irq.chip = NULL; + if (irqchip && + irqchip->irq_request_resources == gpiochip_irq_reqres) { + irqchip->irq_request_resources = NULL; + irqchip->irq_release_resources = NULL; } + gpiochip->irq.chip = NULL; gpiochip_irqchip_free_valid_mask(gpiochip); } @@ -2043,15 +2048,7 @@ int gpiochip_irqchip_add_key(struct gpio_chip *gpiochip, return -EINVAL; } - /* - * It is possible for a driver to override this, but only if the - * alternative functions are both implemented. - */ - if (!irqchip->irq_request_resources && - !irqchip->irq_release_resources) { - irqchip->irq_request_resources = gpiochip_irq_reqres; - irqchip->irq_release_resources = gpiochip_irq_relres; - } + gpiochip_set_irq_hooks(gpiochip); acpi_gpiochip_request_interrupts(gpiochip); From patchwork Sat Sep 8 09:23:16 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Verkuil X-Patchwork-Id: 967584 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) 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=xs4all.nl Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 426pl62VWkz9s3C for ; Sat, 8 Sep 2018 19:23:30 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726390AbeIHOIa (ORCPT ); Sat, 8 Sep 2018 10:08:30 -0400 Received: from lb1-smtp-cloud9.xs4all.net ([194.109.24.22]:48183 "EHLO lb1-smtp-cloud9.xs4all.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726351AbeIHOIa (ORCPT ); Sat, 8 Sep 2018 10:08:30 -0400 Received: from tschai.fritz.box ([212.251.195.8]) by smtp-cloud9.xs4all.net with ESMTPA id yZSZf0zAxMsEFyZSef6TGQ; Sat, 08 Sep 2018 11:23:25 +0200 From: Hans Verkuil To: linux-gpio@vger.kernel.org Cc: Linus Walleij , ilina@codeaurora.org, Marc Zyngier , Thomas Gleixner , Hans Verkuil Subject: [PATCHv2 3/6] gpiolib: add flag to indicate if the irq is disabled Date: Sat, 8 Sep 2018 11:23:16 +0200 Message-Id: <20180908092319.43900-4-hverkuil@xs4all.nl> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180908092319.43900-1-hverkuil@xs4all.nl> References: <20180908092319.43900-1-hverkuil@xs4all.nl> X-CMAE-Envelope: MS4wfEZPC397w2DJFn/JQRCbOYlQ0QVeCH0/pgr0ucHfq/ADRVKZxYtJx79nQBxpWCwFhn15W473YnUOdS18tOh8L12N+tBKVEzrCbIyPLWiyAa5kSVLTpIf wu1J1jc5tBji7ns6p5GGn9iSRy0+d6lwkD8pk7mi4q8YHdYHfs/1juamh5QL6JliyrtoKR6ii1Z8sygauAQ9M2yBCETNxYZPr3XctjxN/shlYqU/3Iq288jq PHPbfF7NEmRJeBQ1xKARy4WH+yFOqMxiCAqCSxgYi/KJXTfdyDan80wp1O11MKUZ0akDtOvp5VrDC+7RlOojLr6R2N37AwVaFKlMA32a1OKQKl2OyZQf5CPN oyHX4hl2 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Hans Verkuil GPIO drivers call gpiochip_(un)lock_as_irq whenever they want to use a gpio as an interrupt. This is done when the irq is requested and it marks the gpio as in use by an interrupt. This is problematic for cases where a gpio pin is used as an interrupt pin, then, after the irq is disabled, is used as a regular gpio pin. Currently it is not possible to do this other than by first freeing the interrupt so gpiochip_unlock_as_irq is called, since an attempt to switch the gpio direction for output will fail since gpiolib believes that the gpio is in use for an interrupt and it does not know that it the irq is actually disabled. There are currently two drivers that would like to be able to do this: the tda998x_drv.c driver where a regular gpio pin needs to be temporarily reconfigured as an interrupt pin during CEC calibration, and the cec-gpio driver where you want to configure the gpio pin as an interrupt while waiting for traffic over the CEC bus, or as a regular pin when receiving or transmitting a CEC message. The solution is to add a new flag that is set when the irq is enabled, and have gpiod_direction_output check for that flag. We also add functions that drivers that do not use GPIOLIB_IRQCHIP can call when they enable/disable the irq. Signed-off-by: Hans Verkuil --- drivers/gpio/gpiolib.c | 29 +++++++++++++++++++++++++++-- drivers/gpio/gpiolib.h | 1 + include/linux/gpio/driver.h | 2 ++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index b17f1142c70b..e52fa72f13d7 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -2588,8 +2588,9 @@ int gpiod_direction_output(struct gpio_desc *desc, int value) else value = !!value; - /* GPIOs used for IRQs shall not be set as output */ - if (test_bit(FLAG_USED_AS_IRQ, &desc->flags)) { + /* GPIOs used for enabled IRQs shall not be set as output */ + if (test_bit(FLAG_USED_AS_IRQ, &desc->flags) && + test_bit(FLAG_IRQ_IS_ENABLED, &desc->flags)) { gpiod_err(desc, "%s: tried to set a GPIO tied to an IRQ as output\n", __func__); @@ -3276,6 +3277,7 @@ int gpiochip_lock_as_irq(struct gpio_chip *chip, unsigned int offset) } set_bit(FLAG_USED_AS_IRQ, &desc->flags); + set_bit(FLAG_IRQ_IS_ENABLED, &desc->flags); /* * If the consumer has not set up a label (such as when the @@ -3306,6 +3308,7 @@ void gpiochip_unlock_as_irq(struct gpio_chip *chip, unsigned int offset) return; clear_bit(FLAG_USED_AS_IRQ, &desc->flags); + clear_bit(FLAG_IRQ_IS_ENABLED, &desc->flags); /* If we only had this marking, erase it */ if (desc->label && !strcmp(desc->label, "interrupt")) @@ -3313,6 +3316,28 @@ void gpiochip_unlock_as_irq(struct gpio_chip *chip, unsigned int offset) } EXPORT_SYMBOL_GPL(gpiochip_unlock_as_irq); +void gpiochip_disable_irq(struct gpio_chip *chip, unsigned int offset) +{ + struct gpio_desc *desc = gpiochip_get_desc(chip, offset); + + if (!IS_ERR(desc) && + !WARN_ON(!test_bit(FLAG_USED_AS_IRQ, &desc->flags))) + clear_bit(FLAG_IRQ_IS_ENABLED, &desc->flags); +} +EXPORT_SYMBOL_GPL(gpiochip_disable_irq); + +void gpiochip_enable_irq(struct gpio_chip *chip, unsigned int offset) +{ + struct gpio_desc *desc = gpiochip_get_desc(chip, offset); + + if (!IS_ERR(desc) && + !WARN_ON(!test_bit(FLAG_USED_AS_IRQ, &desc->flags))) { + WARN_ON(test_bit(FLAG_IS_OUT, &desc->flags)); + set_bit(FLAG_IRQ_IS_ENABLED, &desc->flags); + } +} +EXPORT_SYMBOL_GPL(gpiochip_enable_irq); + bool gpiochip_line_is_irq(struct gpio_chip *chip, unsigned int offset) { if (offset >= chip->ngpio) diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index a7e49fef73d4..e9a86f4b00e3 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -214,6 +214,7 @@ struct gpio_desc { #define FLAG_OPEN_DRAIN 7 /* Gpio is open drain type */ #define FLAG_OPEN_SOURCE 8 /* Gpio is open source type */ #define FLAG_USED_AS_IRQ 9 /* GPIO is connected to an IRQ */ +#define FLAG_IRQ_IS_ENABLED 10 /* GPIO is connected to an enabled IRQ */ #define FLAG_IS_HOGGED 11 /* GPIO is hogged */ #define FLAG_TRANSITORY 12 /* GPIO may lose value in sleep or reset */ diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 380251955ad1..b3dcb7018714 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -397,6 +397,8 @@ void gpiochip_unlock_as_irq(struct gpio_chip *chip, unsigned int offset); bool gpiochip_line_is_irq(struct gpio_chip *chip, unsigned int offset); int gpiochip_reqres_irq(struct gpio_chip *chip, unsigned int offset); void gpiochip_relres_irq(struct gpio_chip *chip, unsigned int offset); +void gpiochip_disable_irq(struct gpio_chip *chip, unsigned int offset); +void gpiochip_enable_irq(struct gpio_chip *chip, unsigned int offset); /* Line status inquiry for drivers */ bool gpiochip_line_is_open_drain(struct gpio_chip *chip, unsigned int offset); From patchwork Sat Sep 8 09:23:17 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Verkuil X-Patchwork-Id: 967587 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) 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=xs4all.nl Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 426pl824qQz9s3Z for ; Sat, 8 Sep 2018 19:23:32 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726315AbeIHOIb (ORCPT ); Sat, 8 Sep 2018 10:08:31 -0400 Received: from lb2-smtp-cloud9.xs4all.net ([194.109.24.26]:53523 "EHLO lb2-smtp-cloud9.xs4all.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726370AbeIHOIb (ORCPT ); Sat, 8 Sep 2018 10:08:31 -0400 Received: from tschai.fritz.box ([212.251.195.8]) by smtp-cloud9.xs4all.net with ESMTPA id yZSZf0zAxMsEFyZSff6TGY; Sat, 08 Sep 2018 11:23:25 +0200 From: Hans Verkuil To: linux-gpio@vger.kernel.org Cc: Linus Walleij , ilina@codeaurora.org, Marc Zyngier , Thomas Gleixner , Hans Verkuil Subject: [PATCHv2 4/6] gpiolib: override irq_enable/disable Date: Sat, 8 Sep 2018 11:23:17 +0200 Message-Id: <20180908092319.43900-5-hverkuil@xs4all.nl> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180908092319.43900-1-hverkuil@xs4all.nl> References: <20180908092319.43900-1-hverkuil@xs4all.nl> X-CMAE-Envelope: MS4wfEZPC397w2DJFn/JQRCbOYlQ0QVeCH0/pgr0ucHfq/ADRVKZxYtJx79nQBxpWCwFhn15W473YnUOdS18tOh8L12N+tBKVEzrCbIyPLWiyAa5kSVLTpIf wu1J1jc5tBji7ns6p5GGn9iSRy0+d6lwkD8pk7mi4q8YHdYHfs/1juamh5QL6JliyrtoKR6ii1Z8sygauAQ9M2yBCETNxYZPr3XctjxN/shlYqU/3Iq288jq PHPbfF7NEmRJeBQ1xKARy4WH+yFOqMxiCAqCSxgYi/KJXTfdyDan80wp1O11MKUZ0akDtOvp5VrDC+7RlOojLr6R2N37AwVaFKlMA32a1OKQKl2OyZQf5CPN oyHX4hl2 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Hans Verkuil When using the gpiolib irqchip helpers install irq_enable/disable hooks for the irqchip to ensure that gpiolib knows when the irq is enabled or disabled, allowing drivers to disable the irq and then use it as an output pin, and later switch the direction to input and re-enable the irq. Signed-off-by: Hans Verkuil --- drivers/gpio/gpiolib.c | 43 +++++++++++++++++++++++++++++++++---- include/linux/gpio/driver.h | 14 ++++++++++++ 2 files changed, 53 insertions(+), 4 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index e52fa72f13d7..efce534a269b 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1826,6 +1826,28 @@ static void gpiochip_irq_relres(struct irq_data *d) gpiochip_relres_irq(chip, d->hwirq); } +static void gpiochip_irq_enable(struct irq_data *d) +{ + struct gpio_chip *chip = irq_data_get_irq_chip_data(d); + + gpiochip_enable_irq(chip, d->hwirq); + if (chip->irq.irq_enable) + chip->irq.irq_enable(d); + else + chip->irq.chip->irq_unmask(d); +} + +static void gpiochip_irq_disable(struct irq_data *d) +{ + struct gpio_chip *chip = irq_data_get_irq_chip_data(d); + + if (chip->irq.irq_disable) + chip->irq.irq_disable(d); + else + chip->irq.chip->irq_mask(d); + gpiochip_disable_irq(chip, d->hwirq); +} + static void gpiochip_set_irq_hooks(struct gpio_chip *gpiochip) { struct irq_chip *irqchip = gpiochip->irq.chip; @@ -1835,6 +1857,12 @@ static void gpiochip_set_irq_hooks(struct gpio_chip *gpiochip) irqchip->irq_request_resources = gpiochip_irq_reqres; irqchip->irq_release_resources = gpiochip_irq_relres; } + if (WARN_ON(gpiochip->irq.irq_enable)) + return; + gpiochip->irq.irq_enable = irqchip->irq_enable; + gpiochip->irq.irq_disable = irqchip->irq_disable; + irqchip->irq_enable = gpiochip_irq_enable; + irqchip->irq_disable = gpiochip_irq_disable; } /** @@ -1954,11 +1982,18 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip) irq_domain_remove(gpiochip->irq.domain); } - if (irqchip && - irqchip->irq_request_resources == gpiochip_irq_reqres) { - irqchip->irq_request_resources = NULL; - irqchip->irq_release_resources = NULL; + if (irqchip) { + if (irqchip->irq_request_resources == gpiochip_irq_reqres) { + irqchip->irq_request_resources = NULL; + irqchip->irq_release_resources = NULL; + } + if (irqchip->irq_enable == gpiochip_irq_enable) { + irqchip->irq_enable = gpiochip->irq.irq_enable; + irqchip->irq_disable = gpiochip->irq.irq_disable; + } } + gpiochip->irq.irq_enable = NULL; + gpiochip->irq.irq_disable = NULL; gpiochip->irq.chip = NULL; gpiochip_irqchip_free_valid_mask(gpiochip); diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index b3dcb7018714..c30ee6fa5d19 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -138,6 +138,20 @@ struct gpio_irq_chip { * will allocate and map all IRQs during initialization. */ unsigned int first; + + /** + * @irq_enable: + * + * Store old irq_chip irq_enable callback + */ + void (*irq_enable)(struct irq_data *data); + + /** + * @irq_disable: + * + * Store old irq_chip irq_disable callback + */ + void (*irq_disable)(struct irq_data *data); }; static inline struct gpio_irq_chip *to_gpio_irq_chip(struct irq_chip *chip) From patchwork Sat Sep 8 09:23:18 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Verkuil X-Patchwork-Id: 967586 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) 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=xs4all.nl Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 426pl74Nqnz9s3C for ; Sat, 8 Sep 2018 19:23:31 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726341AbeIHOIb (ORCPT ); Sat, 8 Sep 2018 10:08:31 -0400 Received: from lb3-smtp-cloud9.xs4all.net ([194.109.24.30]:32937 "EHLO lb3-smtp-cloud9.xs4all.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726315AbeIHOIb (ORCPT ); Sat, 8 Sep 2018 10:08:31 -0400 Received: from tschai.fritz.box ([212.251.195.8]) by smtp-cloud9.xs4all.net with ESMTPA id yZSZf0zAxMsEFyZSff6TGk; Sat, 08 Sep 2018 11:23:25 +0200 From: Hans Verkuil To: linux-gpio@vger.kernel.org Cc: Linus Walleij , ilina@codeaurora.org, Marc Zyngier , Thomas Gleixner , Hans Verkuil Subject: [PATCHv2 5/6] gpio/driver.rst: document gpiochip_disable/enable_irq() Date: Sat, 8 Sep 2018 11:23:18 +0200 Message-Id: <20180908092319.43900-6-hverkuil@xs4all.nl> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180908092319.43900-1-hverkuil@xs4all.nl> References: <20180908092319.43900-1-hverkuil@xs4all.nl> X-CMAE-Envelope: MS4wfEZPC397w2DJFn/JQRCbOYlQ0QVeCH0/pgr0ucHfq/ADRVKZxYtJx79nQBxpWCwFhn15W473YnUOdS18tOh8L12N+tBKVEzrCbIyPLWiyAa5kSVLTpIf wu1J1jc5tBji7ns6p5GGn9iSRy0+d6lwkD8pk7mi4q8YHdYHfs/1juamh5QL6JliyrtoKR6ii1Z8sygauAQ9M2yBCETNxYZPr3XctjxN/shlYqU/3Iq288jq PHPbfF7NEmRJeBQ1xKARy4WH+yFOqMxiCAqCSxgYi/KJXTfdyDan80wp1O11MKUZ0akDtOvp5VrDC+7RlOojLr6R2N37AwVaFKlMA32a1OKQKl2OyZQf5CPN oyHX4hl2 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Hans Verkuil Document these new functions. Signed-off-by: Hans Verkuil --- Documentation/driver-api/gpio/driver.rst | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/Documentation/driver-api/gpio/driver.rst b/Documentation/driver-api/gpio/driver.rst index cbe0242842d1..a6c14ff0c54f 100644 --- a/Documentation/driver-api/gpio/driver.rst +++ b/Documentation/driver-api/gpio/driver.rst @@ -374,7 +374,28 @@ When implementing an irqchip inside a GPIO driver, these two functions should typically be called in the .startup() and .shutdown() callbacks from the irqchip. -When using the gpiolib irqchip helpers, these callback are automatically +When using the gpiolib irqchip helpers, these callbacks are automatically +assigned. + + +Disabling and enabling IRQs +--------------------------- +When a GPIO is used as an IRQ signal, then gpiolib also needs to know if +the IRQ is enabled or disabled. In order to inform gpiolib about this, +a driver should call:: + + void gpiochip_disable_irq(struct gpio_chip *chip, unsigned int offset) + +This allows drivers to drive the GPIO as an output while the IRQ is +disabled. When the IRQ is enabled again, a driver should call:: + + void gpiochip_enable_irq(struct gpio_chip *chip, unsigned int offset) + +When implementing an irqchip inside a GPIO driver, these two functions should +typically be called in the .irq_disable() and .irq_enable() callbacks from the +irqchip. + +When using the gpiolib irqchip helpers, these callbacks are automatically assigned. Real-Time compliance for GPIO IRQ chips From patchwork Sat Sep 8 09:23:19 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Verkuil X-Patchwork-Id: 967588 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) 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=xs4all.nl Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 426pl86s5gz9s3C for ; Sat, 8 Sep 2018 19:23:32 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726370AbeIHOIb (ORCPT ); Sat, 8 Sep 2018 10:08:31 -0400 Received: from lb2-smtp-cloud9.xs4all.net ([194.109.24.26]:52149 "EHLO lb2-smtp-cloud9.xs4all.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726333AbeIHOIb (ORCPT ); Sat, 8 Sep 2018 10:08:31 -0400 Received: from tschai.fritz.box ([212.251.195.8]) by smtp-cloud9.xs4all.net with ESMTPA id yZSZf0zAxMsEFyZSff6TGr; Sat, 08 Sep 2018 11:23:26 +0200 From: Hans Verkuil To: linux-gpio@vger.kernel.org Cc: Linus Walleij , ilina@codeaurora.org, Marc Zyngier , Thomas Gleixner , Hans Verkuil , Ray Jui Subject: [PATCHv2 6/6] gpio-bcm-kona: use new req/relres and dis/enable_irq funcs Date: Sat, 8 Sep 2018 11:23:19 +0200 Message-Id: <20180908092319.43900-7-hverkuil@xs4all.nl> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180908092319.43900-1-hverkuil@xs4all.nl> References: <20180908092319.43900-1-hverkuil@xs4all.nl> X-CMAE-Envelope: MS4wfNU2qOxcJxF7sItaN4jGAJGKNIJpTkQzRGddOG9XvnY+UeydaqPEJlQJAEV3CibQjoiCVZq01BoVKk4j4DqlZRorctJLIVAoBIJDu20v09H6Napuwo6e nlxGyMK9iIx7qLETjToSC2GCJsKpgrIaG9uB1+oj0ijBEK5j+D86+mH6B/xd61Uy8aJyMp/IaFP5yUwrL642a9n830xVpkCRaf+9F/A/P86sV6imSLG3oHK3 bW4hjkmkOhI0EmTSPyKxSjjFcUgH6/WnUywAiZyGpwAvWOVYiKhI2il6oX6C+iyM+qZ+EKyPNHu5ULPZWNxAeUU5Mf+JxG0ihue6XtXQJ0tweVbcpnl6XFEc g6wTXVa589EDW1LrgfPBxlhS1SVcNw== Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Hans Verkuil Since this driver does not use the gpiolib irqchip helpers it will have to allocate the irq resources and irq_en/disable itself. Use the new gpiochip_req/relres_irq helpers to request/release all the resources. Signed-off-by: Hans Verkuil Cc: Ray Jui --- drivers/gpio/gpio-bcm-kona.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/gpio/gpio-bcm-kona.c b/drivers/gpio/gpio-bcm-kona.c index d0707fc23afd..c5536a509b59 100644 --- a/drivers/gpio/gpio-bcm-kona.c +++ b/drivers/gpio/gpio-bcm-kona.c @@ -373,6 +373,7 @@ static void bcm_kona_gpio_irq_mask(struct irq_data *d) val = readl(reg_base + GPIO_INT_MASK(bank_id)); val |= BIT(bit); writel(val, reg_base + GPIO_INT_MASK(bank_id)); + gpiochip_disable_irq(&kona_gpio->gpio_chip, gpio); raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); } @@ -394,6 +395,7 @@ static void bcm_kona_gpio_irq_unmask(struct irq_data *d) val = readl(reg_base + GPIO_INT_MSKCLR(bank_id)); val |= BIT(bit); writel(val, reg_base + GPIO_INT_MSKCLR(bank_id)); + gpiochip_enable_irq(&kona_gpio->gpio_chip, gpio); raw_spin_unlock_irqrestore(&kona_gpio->lock, flags); } @@ -485,23 +487,15 @@ static void bcm_kona_gpio_irq_handler(struct irq_desc *desc) static int bcm_kona_gpio_irq_reqres(struct irq_data *d) { struct bcm_kona_gpio *kona_gpio = irq_data_get_irq_chip_data(d); - int ret; - ret = gpiochip_lock_as_irq(&kona_gpio->gpio_chip, d->hwirq); - if (ret) { - dev_err(kona_gpio->gpio_chip.parent, - "unable to lock HW IRQ %lu for IRQ\n", - d->hwirq); - return ret; - } - return 0; + return gpiochip_reqres_irq(&kona_gpio->gpio_chip, d->hwirq); } static void bcm_kona_gpio_irq_relres(struct irq_data *d) { struct bcm_kona_gpio *kona_gpio = irq_data_get_irq_chip_data(d); - gpiochip_unlock_as_irq(&kona_gpio->gpio_chip, d->hwirq); + gpiochip_relres_irq(&kona_gpio->gpio_chip, d->hwirq); } static struct irq_chip bcm_gpio_irq_chip = {