From patchwork Tue Oct 4 15:08:22 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jerome Brunet X-Patchwork-Id: 9361989 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 D1078600C8 for ; Tue, 4 Oct 2016 15:11:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C138628450 for ; Tue, 4 Oct 2016 15:11:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B5DCB28BF4; Tue, 4 Oct 2016 15:11:43 +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 B39CF28450 for ; Tue, 4 Oct 2016 15:11:39 +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 1brRMB-0003e5-BJ; Tue, 04 Oct 2016 15:10:11 +0000 Received: from mail-wm0-x236.google.com ([2a00:1450:400c:c09::236]) by bombadil.infradead.org with esmtps (Exim 4.85_2 #1 (Red Hat Linux)) id 1brRL8-00027h-Pn for linux-arm-kernel@lists.infradead.org; Tue, 04 Oct 2016 15:09:11 +0000 Received: by mail-wm0-x236.google.com with SMTP id b201so150776153wmb.0 for ; Tue, 04 Oct 2016 08:08:49 -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=yDjdpwInLL+J4bHYqGYiiC+LPja+ZKnlWODFfLlF2gw=; b=03txVCZSTvlUSvfBPIFBekwhqPi4wrC0yrCoe+B1ruxnggO0XNTccGm7z/PeXHOBl/ fZiayQqZMFnaGJltaS2ZHDi30p9N1rB5HnTJ6Y6qh2ebH6IQim0DXUcXFtsjCdyp0ZfE IOgJwXCylIJmWSqnA+LQBeppc9XNWKZoZskoTR6ikXQSW27V9JaQgY6o6FxDRItUjvcu GFF27XmVHf0s7y8zCm+7GMO9wVmNWGPlt2rj9sDMKa2AaO1UWEcavjXN5BW0MVqKVYin XL0w+J4FccZF3xPdBR1yNG2J/fzEnCXi2VueiJgL44J0jLjOX9/hE83pYD2QKlQf7CPQ at3A== 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=yDjdpwInLL+J4bHYqGYiiC+LPja+ZKnlWODFfLlF2gw=; b=X7CUgcNt1KctpAXunm+esgMnskQHpJ2+UNPWqHeAjgkv9xGfY7XXMx4GOa0//cYc2L hL9uFFDHo8T2qWAm0Xmm779DxGNIJbvDcOqZ0KUd9RKL3Zux7jNFXdM8GMjzyS4DfJcO YTsNsGfpAGD8j78mral0FdJmO8SU83hrC9iiDkGD1SB3MaslczoUjCIHCA3SN6mX7UNr 6KKfACYBztejp6IBXXlpCe1PSTHW7XVl4c6wM/qq1DO5do+QhPov1doVR78ibCPq9X5n AfmRRJCdpBIpdHD5YtaQT2baZwipM3K9pr9/NsJL1BCxirXU3Nqnoak2fixsqYtqGzFE ljWA== X-Gm-Message-State: AA6/9Rk9JSjZMTHEMVMMgogCoheHXwiqHloyn8UuHgxfk5xNrY7WzP1rOnFww0f5FqYkRt5/ X-Received: by 10.28.29.4 with SMTP id d4mr4069935wmd.111.1475593728217; Tue, 04 Oct 2016 08:08:48 -0700 (PDT) Received: from boomer.baylibre.com ([90.63.244.31]) by smtp.googlemail.com with ESMTPSA id j198sm4583539wmg.4.2016.10.04.08.08.47 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 04 Oct 2016 08:08:47 -0700 (PDT) From: Jerome Brunet To: Kevin Hilman , Carlo Caione , Thomas Gleixner , Jason Cooper , Marc Zyngier Subject: [RFC 04/10] pinctrl: meson: allow gpio to request irq Date: Tue, 4 Oct 2016 17:08:22 +0200 Message-Id: <1475593708-10526-5-git-send-email-jbrunet@baylibre.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1475593708-10526-1-git-send-email-jbrunet@baylibre.com> References: <1475593708-10526-1-git-send-email-jbrunet@baylibre.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20161004_080907_251973_41E0DD07 X-CRM114-Status: GOOD ( 18.53 ) 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: linux-amlogic@lists.infradead.org, devicetree@vger.kernel.org, linux-gpio@vger.kernel.org, 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 | 83 ++++++++++++++++++++++++++++++++++- drivers/pinctrl/meson/pinctrl-meson.h | 1 + 3 files changed, 85 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..f9be3ff5e11d 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,33 @@ 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; + + /* + * Make sure gpio don't request IRQ directly to the GIC + * TODO: Find a better way to make sure we have a compatible + * Interrupt controller here + */ + if (!of_get_property(node, "interrupt-parent", NULL)) { + dev_dbg(pc->dev, "interrupt controller not found\n"); + pc->fwnode = NULL; + return 0; + } + + np = of_irq_find_parent(node); + if (!np) { + dev_err(pc->dev, "irq parent not found\n"); + return -EINVAL; + } + + 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 +724,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 785705996e60..4bcc4900b3eb 100644 --- a/drivers/pinctrl/meson/pinctrl-meson.h +++ b/drivers/pinctrl/meson/pinctrl-meson.h @@ -122,6 +122,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)