From patchwork Wed Oct 19 10:08:24 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jerome Brunet X-Patchwork-Id: 9383775 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 22B7860487 for ; Wed, 19 Oct 2016 10:11:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 127DD29908 for ; Wed, 19 Oct 2016 10:11:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 06B6F2990A; Wed, 19 Oct 2016 10:11:48 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED, T_DKIM_INVALID autolearn=unavailable version=3.3.1 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.wl.linuxfoundation.org (Postfix) with ESMTPS id 7761629908 for ; Wed, 19 Oct 2016 10:11:45 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1bwnp9-0006EH-Lr; Wed, 19 Oct 2016 10:10:15 +0000 Received: from mail-wm0-x22b.google.com ([2a00:1450:400c:c09::22b]) by bombadil.infradead.org with esmtps (Exim 4.85_2 #1 (Red Hat Linux)) id 1bwnoL-0005JB-IU for linux-arm-kernel@lists.infradead.org; Wed, 19 Oct 2016 10:09:28 +0000 Received: by mail-wm0-x22b.google.com with SMTP id c78so50061045wme.0 for ; Wed, 19 Oct 2016 03:09:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=CBIKugDPvE6YZkZlIZ4fS4SNIQVRR1eJoF92Ln/1e7A=; b=OKoKwM9GwsUDXGg5JcDmir4/oZeB2gx9ddXt8+acHKRzh6xDC/bbexUxwf/WWMUk+J 8LpHrmg5BdEAabRe+2J2Hj9WO37gvwaEgyr61I8VXbFaNFuA+Pt3RqwIhAE3omc8fYpz muTcOtKHWDFbaxkjnpq4hdl/mPEO2vGRNEodBChj3ZuClE7KOOycMgZSqmnLhn3P4wsz tWFsIc+ESHIjvDmtxTdqAq1mMRK/F2bG2MhJX0hdtR0WvvsKOr6NnuDKUp+rBxQ3GR3y /xoRj6Y7U+p0TGq5DSP1hErQOYaENQAnQqpbWHGp+8Mrar2dkgOzsRNHKMIXxv3qWcqe 1cog== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=CBIKugDPvE6YZkZlIZ4fS4SNIQVRR1eJoF92Ln/1e7A=; b=IbgVV4g1jwCmIowOZUiUS+Ii2DTt9EkNM1EhnQHn+VtEtEIDf3n+99ocCjS/Imr+F5 aKJoxiwQqm9okryMdj/3ZEtuoAqnBmRBQr8LGbNFc2p09LIK6i/cNgVkblHoY68l1IQp BTrJBIOxuA0mxOqfN1lbC1x7eNJ8JIlW7tt6NPJC4NvboMO23LxeYWxkhz6Mj3gBtaR0 NCiCrEve96jtqrkMUv4HoU6MQpKYchnQf8nN4hBDq7pEJ4VjVlR2VWl9OH8548QXTudt Lp8RSoj/sd6mwhoz2giEp464AgyUE7uFnD4cT2tKy1VyembBnP4G3daT4TrVTwMUXspD XVkQ== X-Gm-Message-State: AA6/9Rk5O/eP8iKC+D5pTrz4fSxqEYwtaP7ZaHFvDdti3H5COyTtZCG2blL2Sna3foFXw0w7 X-Received: by 10.28.18.5 with SMTP id 5mr4364798wms.35.1476871743690; Wed, 19 Oct 2016 03:09:03 -0700 (PDT) Received: from boomer.baylibre.com ([90.63.244.31]) by smtp.googlemail.com with ESMTPSA id l15sm4199066wmd.7.2016.10.19.03.09.02 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 19 Oct 2016 03:09:03 -0700 (PDT) From: Jerome Brunet To: Carlo Caione , Kevin Hilman , Linus Walleij Subject: [PATCH 4/9] pinctrl: meson: allow gpio to request irq Date: Wed, 19 Oct 2016 12:08:24 +0200 Message-Id: <1476871709-8359-5-git-send-email-jbrunet@baylibre.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1476871709-8359-1-git-send-email-jbrunet@baylibre.com> References: <1476871709-8359-1-git-send-email-jbrunet@baylibre.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20161019_030926_144580_9FF56E9E X-CRM114-Status: GOOD ( 18.72 ) 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: devicetree@vger.kernel.org, Jason Cooper , Marc Zyngier , Catalin Marinas , Will Deacon , linux-kernel@vger.kernel.org, Russell King , linux-gpio@vger.kernel.org, Rob Herring , linux-amlogic@lists.infradead.org, Thomas Gleixner , linux-arm-kernel@lists.infradead.org, Jerome Brunet MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Add the ability for gpio to request irq from the gpio interrupt controller if present. We have to specificaly that the parent interrupt controller is the gpio interrupt controller because gpio on meson SoCs can't generate interrupt directly on the GIC. Signed-off-by: Jerome Brunet --- drivers/pinctrl/Kconfig | 2 + drivers/pinctrl/meson/pinctrl-meson.c | 77 ++++++++++++++++++++++++++++++++++- drivers/pinctrl/meson/pinctrl-meson.h | 1 + 3 files changed, 79 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 0e75d94972ba..d5bfbfcddab0 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -126,7 +126,9 @@ config PINCTRL_MESON select PINCONF select GENERIC_PINCONF select GPIOLIB + select IRQ_DOMAIN select OF_GPIO + select OF_IRQ select REGMAP_MMIO config PINCTRL_OXNAS diff --git a/drivers/pinctrl/meson/pinctrl-meson.c b/drivers/pinctrl/meson/pinctrl-meson.c index 57122eda155a..fd3c1d44978b 100644 --- a/drivers/pinctrl/meson/pinctrl-meson.c +++ b/drivers/pinctrl/meson/pinctrl-meson.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -481,6 +482,58 @@ static void meson_gpio_set(struct gpio_chip *chip, unsigned gpio, int value) value ? BIT(bit) : 0); } +static int meson_gpio_to_hwirq(struct meson_bank *bank, unsigned int offset) +{ + unsigned int hwirq; + + if (bank->irq_first < 0) + /* this bank cannot generate irqs */ + return -1; + + hwirq = offset - bank->first + bank->irq_first; + + if (hwirq > bank->irq_last) + /* this pin cannot generate irqs */ + return -1; + + return hwirq; +} + +static int meson_gpio_to_irq(struct gpio_chip *chip, unsigned int offset) +{ + struct meson_pinctrl *pc = gpiochip_get_data(chip); + struct meson_bank *bank; + struct irq_fwspec fwspec; + unsigned int hwirq; + int ret; + + ret = meson_get_bank(pc, offset, &bank); + if (ret) + return ret; + + /* + * The interrupt controller might be missing, in such case we can't + * provide an interrupt for a pin + */ + if (is_fwnode_irqchip(pc->fwnode)) { + dev_info(pc->dev, "interrupt controller not found\n"); + return 0; + } + + hwirq = meson_gpio_to_hwirq(bank, offset); + if (hwirq < 0) { + dev_dbg(pc->dev, "no interrupt for pin %u\n", offset); + return 0; + } + + fwspec.fwnode = pc->fwnode; + fwspec.param_count = 2; + fwspec.param[0] = hwirq; + fwspec.param[1] = IRQ_TYPE_NONE; + + return irq_create_fwspec_mapping(&fwspec); +} + static int meson_gpio_get(struct gpio_chip *chip, unsigned gpio) { struct meson_pinctrl *pc = gpiochip_get_data(chip); @@ -539,6 +592,7 @@ static int meson_gpiolib_register(struct meson_pinctrl *pc) pc->chip.direction_output = meson_gpio_direction_output; pc->chip.get = meson_gpio_get; pc->chip.set = meson_gpio_set; + pc->chip.to_irq = meson_gpio_to_irq; pc->chip.base = pc->data->pin_base; pc->chip.ngpio = pc->data->num_pins; pc->chip.can_sleep = false; @@ -598,6 +652,27 @@ static struct regmap *meson_map_resource(struct meson_pinctrl *pc, return devm_regmap_init_mmio(pc->dev, base, &meson_regmap_config); } +static int meson_pinctrl_get_irq_gpio_intc(struct meson_pinctrl *pc, + struct device_node *node) +{ + struct device_node *np; + + np = of_irq_find_parent(node); + if (unlikely(!np)) { + dev_err(pc->dev, "interrupt parent not found\n"); + return -EINVAL; + } + + if (!of_device_is_compatible(np, pc->data->irq_compat)) { + dev_info(pc->dev, "gpio interrupt disabled\n"); + pc->fwnode = NULL; + } + + pc->fwnode = of_node_to_fwnode(np); + + return 0; +} + static int meson_pinctrl_parse_dt(struct meson_pinctrl *pc, struct device_node *node) { @@ -643,7 +718,7 @@ static int meson_pinctrl_parse_dt(struct meson_pinctrl *pc, return PTR_ERR(pc->reg_gpio); } - return 0; + return meson_pinctrl_get_irq_gpio_intc(pc, gpio_np); } static int meson_pinctrl_probe(struct platform_device *pdev) diff --git a/drivers/pinctrl/meson/pinctrl-meson.h b/drivers/pinctrl/meson/pinctrl-meson.h index b90d69e366df..2e6c83adbd1f 100644 --- a/drivers/pinctrl/meson/pinctrl-meson.h +++ b/drivers/pinctrl/meson/pinctrl-meson.h @@ -123,6 +123,7 @@ struct meson_pinctrl { struct regmap *reg_gpio; struct gpio_chip chip; struct device_node *of_node; + struct fwnode_handle *fwnode; }; #define PIN(x, b) (b + x)