From patchwork Fri Sep 26 12:42:07 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 37963 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-la0-f70.google.com (mail-la0-f70.google.com [209.85.215.70]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 13262202DB for ; Fri, 26 Sep 2014 12:42:34 +0000 (UTC) Received: by mail-la0-f70.google.com with SMTP id s18sf7450331lam.9 for ; Fri, 26 Sep 2014 05:42:33 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:sender:precedence:list-id:x-original-sender :x-original-authentication-results:mailing-list:list-post:list-help :list-archive:list-unsubscribe; bh=WlbXfnBKm0ki0tTzXZBlJVh2XITozpmIE5YX4rpMuFs=; b=acvzYOsF/n+kOJUBfu1jBz2mCWFa0SMqdB/Vgd2ARymW3J0oI7U3ToEwx79w0btPkM eTFm1/qSuGpzrRIq20znqsGhWcOo6BOEOl7QvYzgeB+79l+o2Nxo+u9KcsUD4yucfgUi NB/4JErmbYr/12gU0jNYMlFrtvT2btaJcEep0fEbQGNvaJbynifka6+KvEpDtAyu2xIA LLx8ukhe7vP8zWh2NhDMpQ61R/VTq1H/iCb35Bk1UnsV6T/TUH7lg2rOZXk/JSTA3QFs WhJIRPcnUUdNl/h6wzF5VaH0Kv5qqiV6tfXa5NpvYYQeIiXUl8ZxjFtlprzcBwnBD95C qQYg== X-Gm-Message-State: ALoCoQn+9Wq7Yzwe16L4THxrpF84xt7yIsu2aLI88i0OTv8cL0HCX+C9x6qe2CGULymL0texFYWY X-Received: by 10.194.100.3 with SMTP id eu3mr8221wjb.6.1411735353813; Fri, 26 Sep 2014 05:42:33 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.37.1 with SMTP id u1ls417879laj.20.gmail; Fri, 26 Sep 2014 05:42:33 -0700 (PDT) X-Received: by 10.152.170.194 with SMTP id ao2mr19895904lac.78.1411735353514; Fri, 26 Sep 2014 05:42:33 -0700 (PDT) Received: from mail-la0-f51.google.com (mail-la0-f51.google.com [209.85.215.51]) by mx.google.com with ESMTPS id ap7si7053452lac.63.2014.09.26.05.42.33 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 26 Sep 2014 05:42:33 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.51 as permitted sender) client-ip=209.85.215.51; Received: by mail-la0-f51.google.com with SMTP id pv20so4886831lab.10 for ; Fri, 26 Sep 2014 05:42:33 -0700 (PDT) X-Received: by 10.152.88.16 with SMTP id bc16mr590973lab.56.1411735353182; Fri, 26 Sep 2014 05:42:33 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.130.169 with SMTP id of9csp53893lbb; Fri, 26 Sep 2014 05:42:28 -0700 (PDT) X-Received: by 10.66.151.196 with SMTP id us4mr28855690pab.78.1411735334614; Fri, 26 Sep 2014 05:42:14 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r4si9083690pds.150.2014.09.26.05.42.14 for ; Fri, 26 Sep 2014 05:42:14 -0700 (PDT) Received-SPF: none (google.com: linux-gpio-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754825AbaIZMmN (ORCPT ); Fri, 26 Sep 2014 08:42:13 -0400 Received: from mail-wg0-f47.google.com ([74.125.82.47]:45292 "EHLO mail-wg0-f47.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753707AbaIZMmN (ORCPT ); Fri, 26 Sep 2014 08:42:13 -0400 Received: by mail-wg0-f47.google.com with SMTP id y10so9789302wgg.18 for ; Fri, 26 Sep 2014 05:42:11 -0700 (PDT) X-Received: by 10.194.120.138 with SMTP id lc10mr22811021wjb.55.1411735331104; Fri, 26 Sep 2014 05:42:11 -0700 (PDT) Received: from localhost.localdomain ([85.235.11.236]) by mx.google.com with ESMTPSA id eg8sm2071361wib.15.2014.09.26.05.42.09 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 26 Sep 2014 05:42:10 -0700 (PDT) From: Linus Walleij To: linux-gpio@vger.kernel.org Cc: Alexandre Courbot , Linus Walleij Subject: [PATCH] gpio: handle also nested irqchips in the chained handler set-up Date: Fri, 26 Sep 2014 14:42:07 +0200 Message-Id: <1411735327-30733-1-git-send-email-linus.walleij@linaro.org> X-Mailer: git-send-email 1.9.3 Sender: linux-gpio-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-gpio@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: linus.walleij@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.51 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , To unify how we connect cascaded IRQ chips to parent IRQs, if NULL us passed as handler to the gpiochip_set_chained_irqchip() function, assume the chips is nested rather than chained, and we still get the parent set up correctly by way of this function call. Alter the drivers for tc3589x and stmpe to use this to set up their chained handlers as a demonstration of the usage. Signed-off-by: Linus Walleij --- Documentation/gpio/driver.txt | 3 ++- drivers/gpio/gpio-stmpe.c | 18 ++++++++++++------ drivers/gpio/gpio-tc3589x.c | 5 +++++ drivers/gpio/gpiolib.c | 34 +++++++++++++++++++--------------- 4 files changed, 38 insertions(+), 22 deletions(-) diff --git a/Documentation/gpio/driver.txt b/Documentation/gpio/driver.txt index 23b751a10d7b..31e0b5db55d8 100644 --- a/Documentation/gpio/driver.txt +++ b/Documentation/gpio/driver.txt @@ -124,7 +124,8 @@ symbol: * gpiochip_set_chained_irqchip(): sets up a chained irq handler for a gpio_chip from a parent IRQ and passes the struct gpio_chip* as handler data. (Notice handler data, since the irqchip data is likely used by the - parent irqchip!) This is for the chained type of chip. + parent irqchip!) This is for the chained type of chip. This is also used + to set up a nested irqchip if NULL is passed as handler. To use the helpers please keep the following in mind: diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c index 845025a57240..b0b342787c37 100644 --- a/drivers/gpio/gpio-stmpe.c +++ b/drivers/gpio/gpio-stmpe.c @@ -308,6 +308,12 @@ static int stmpe_gpio_probe(struct platform_device *pdev) if (ret) goto out_free; + ret = gpiochip_add(&stmpe_gpio->chip); + if (ret) { + dev_err(&pdev->dev, "unable to add gpiochip: %d\n", ret); + goto out_disable; + } + if (irq > 0) { ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, stmpe_gpio_irq, IRQF_ONESHOT, @@ -324,14 +330,13 @@ static int stmpe_gpio_probe(struct platform_device *pdev) if (ret) { dev_err(&pdev->dev, "could not connect irqchip to gpiochip\n"); - return ret; + goto out_disable; } - } - ret = gpiochip_add(&stmpe_gpio->chip); - if (ret) { - dev_err(&pdev->dev, "unable to add gpiochip: %d\n", ret); - goto out_disable; + gpiochip_set_chained_irqchip(&stmpe_gpio->chip, + &stmpe_gpio_irq_chip, + irq, + NULL); } if (pdata && pdata->setup) @@ -343,6 +348,7 @@ static int stmpe_gpio_probe(struct platform_device *pdev) out_disable: stmpe_disable(stmpe, STMPE_BLOCK_GPIO); + gpiochip_remove(&stmpe_gpio->chip); out_free: kfree(stmpe_gpio); return ret; diff --git a/drivers/gpio/gpio-tc3589x.c b/drivers/gpio/gpio-tc3589x.c index 7324869c38e0..ae0f6466eb09 100644 --- a/drivers/gpio/gpio-tc3589x.c +++ b/drivers/gpio/gpio-tc3589x.c @@ -300,6 +300,11 @@ static int tc3589x_gpio_probe(struct platform_device *pdev) return ret; } + gpiochip_set_chained_irqchip(&tc3589x_gpio->chip, + &tc3589x_gpio_irq_chip, + irq, + NULL); + if (pdata && pdata->setup) pdata->setup(tc3589x, tc3589x_gpio->chip.base); diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 9362b5b817af..6e00c82be142 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -385,13 +385,14 @@ static struct gpio_chip *find_chip_by_name(const char *name) */ /** - * gpiochip_add_chained_irqchip() - adds a chained irqchip to a gpiochip - * @gpiochip: the gpiochip to add the irqchip to - * @irqchip: the irqchip to add to the gpiochip + * gpiochip_set_chained_irqchip() - sets a chained irqchip to a gpiochip + * @gpiochip: the gpiochip to set the irqchip chain to + * @irqchip: the irqchip to chain to the gpiochip * @parent_irq: the irq number corresponding to the parent IRQ for this * chained irqchip * @parent_handler: the parent interrupt handler for the accumulated IRQ - * coming out of the gpiochip + * coming out of the gpiochip. If the interrupt is nested rather than + * cascaded, pass NULL in this handler argument */ void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip, struct irq_chip *irqchip, @@ -400,23 +401,26 @@ void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip, { unsigned int offset; - if (gpiochip->can_sleep) { - chip_err(gpiochip, "you cannot have chained interrupts on a chip that may sleep\n"); - return; - } if (!gpiochip->irqdomain) { chip_err(gpiochip, "called %s before setting up irqchip\n", __func__); return; } - irq_set_chained_handler(parent_irq, parent_handler); - - /* - * The parent irqchip is already using the chip_data for this - * irqchip, so our callbacks simply use the handler_data. - */ - irq_set_handler_data(parent_irq, gpiochip); + if (parent_handler) { + if (gpiochip->can_sleep) { + chip_err(gpiochip, + "you cannot have chained interrupts on a " + "chip that may sleep\n"); + return; + } + irq_set_chained_handler(parent_irq, parent_handler); + /* + * The parent irqchip is already using the chip_data for this + * irqchip, so our callbacks simply use the handler_data. + */ + irq_set_handler_data(parent_irq, gpiochip); + } /* Set the parent IRQ for all affected IRQs */ for (offset = 0; offset < gpiochip->ngpio; offset++)