From patchwork Sat Oct 17 17:23:55 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Coquelin X-Patchwork-Id: 7422931 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 EEEA2BEEA4 for ; Sat, 17 Oct 2015 17:29:35 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 1481520494 for ; Sat, 17 Oct 2015 17:29:35 +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 E23612063D for ; Sat, 17 Oct 2015 17:29:33 +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 1ZnVH0-0002T5-Ir; Sat, 17 Oct 2015 17:28:02 +0000 Received: from mail-wi0-x22b.google.com ([2a00:1450:400c:c05::22b]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZnVDb-00042C-Gh for linux-arm-kernel@lists.infradead.org; Sat, 17 Oct 2015 17:24:32 +0000 Received: by wicfv8 with SMTP id fv8so28245635wic.0 for ; Sat, 17 Oct 2015 10:24:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=RS1v0zznADepcwdZmlGiICSpnDpCyNmieOnXwxQbyhM=; b=ariCdlDIWJrWIR/59GQP2dmAx628zQpnfs4t1lSiDFDhiQcpUZlOca4CNx/hokOXmW PcvCwbfQxpStUkbKeeHjFcpp0aGH0wm8rfaCcPK8KKQbJQ7LJnoeEur+NHA3suCOH8Yn F8yA6l2ThOYHL7iqeHyyNtlFWNG0Ynp2W1Zp6kSGAwwZKsw8Xsrb8/JbqlQlSK3HXGGS K7VbDk7I3j2TivREs1Iv1MmXO0GJnd4tfSXlyv0wRoSfq9+h95uyp0UNm/NNg+pHoXg1 o85aabAw2BY/MhY+ry/Cpsnte1fLffOhGw6ZZD/1rdCPGG+rkZkiZoYSutY3Aqu6RnP6 smrQ== X-Received: by 10.180.108.110 with SMTP id hj14mr12124091wib.39.1445102649920; Sat, 17 Oct 2015 10:24:09 -0700 (PDT) Received: from lmecul0520.st.com. (101.210.139.88.rev.sfr.net. [88.139.210.101]) by smtp.gmail.com with ESMTPSA id gh9sm29409201wjb.27.2015.10.17.10.24.08 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 17 Oct 2015 10:24:09 -0700 (PDT) From: Maxime Coquelin To: Thomas Gleixner , Jason Cooper , Marc Zyngier , Linus Walleij , Mark Rutland , Rob Herring , linux-gpio@vger.kernel.org, arnd@arndb.de Subject: [PATCH 6/9] pinctrl: Add IRQ support to STM32 gpios Date: Sat, 17 Oct 2015 19:23:55 +0200 Message-Id: <1445102638-11575-7-git-send-email-mcoquelin.stm32@gmail.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1445102638-11575-1-git-send-email-mcoquelin.stm32@gmail.com> References: <1445102638-11575-1-git-send-email-mcoquelin.stm32@gmail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20151017_102431_793245_589E9028 X-CRM114-Status: GOOD ( 18.59 ) X-Spam-Score: -2.5 (--) 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, Daniel Thompson , bruherrera@gmail.com, linux-kernel@vger.kernel.org, afaerber@suse.de, 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.1 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, T_DKIM_INVALID, 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 This patch adds IRQ support to STM32 gpios. The EXTI controller has 16 lines dedicated to GPIOs. EXTI line n can be connected to only line n of one of the GPIO ports, for example EXTI0 can be connected to either PA0, or PB0, or PC0... This port selection is done by specifying the port number into System Config registers. Signed-off-by: Maxime Coquelin --- drivers/pinctrl/stm32/Kconfig | 1 + drivers/pinctrl/stm32/pinctrl-stm32.c | 68 +++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/drivers/pinctrl/stm32/Kconfig b/drivers/pinctrl/stm32/Kconfig index 0f28841..b5cac5b 100644 --- a/drivers/pinctrl/stm32/Kconfig +++ b/drivers/pinctrl/stm32/Kconfig @@ -6,6 +6,7 @@ config PINCTRL_STM32 select PINMUX select GENERIC_PINCONF select GPIOLIB + select MFD_SYSCON config PINCTRL_STM32F429 bool "STMicroelectronics STM32F429 pin control" if COMPILE_TEST && !MACH_STM32F429 diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c index 4ebceaa..954b596 100644 --- a/drivers/pinctrl/stm32/pinctrl-stm32.c +++ b/drivers/pinctrl/stm32/pinctrl-stm32.c @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include #include #include @@ -20,6 +22,7 @@ #include #include #include +#include #include #include @@ -82,6 +85,9 @@ struct stm32_pinctrl { struct stm32_gpio_bank *banks; unsigned nbanks; const struct stm32_pinctrl_match_data *match_data; + struct irq_domain *domain; + struct regmap *regmap; + struct regmap_field *irqmux[STM32_GPIO_PINS_PER_BANK]; }; static inline int stm32_gpio_pin(int gpio) @@ -179,6 +185,22 @@ static int stm32_gpio_direction_output(struct gpio_chip *chip, return 0; } + +static int stm32_gpio_to_irq(struct gpio_chip *chip, unsigned offset) +{ + struct stm32_pinctrl *pctl = dev_get_drvdata(chip->dev); + struct stm32_gpio_bank *bank = gpio_chip_to_bank(chip); + unsigned int virq; + + regmap_field_write(pctl->irqmux[offset], bank->range.id); + + virq = irq_create_mapping(pctl->domain, offset); + if (!virq) + return -ENXIO; + + return virq; +} + static struct gpio_chip stm32_gpio_template = { .request = stm32_gpio_request, .free = stm32_gpio_free, @@ -186,6 +208,7 @@ static struct gpio_chip stm32_gpio_template = { .set = stm32_gpio_set, .direction_input = stm32_gpio_direction_input, .direction_output = stm32_gpio_direction_output, + .to_irq = stm32_gpio_to_irq, }; /* Pinctrl functions */ @@ -731,6 +754,47 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, return 0; } +static int stm32_pctrl_dt_setup_irq(struct platform_device *pdev, + struct stm32_pinctrl *pctl) +{ + struct device_node *np = pdev->dev.of_node, *parent; + struct device *dev = &pdev->dev; + struct regmap *rm; + int offset, ret, i; + + parent = of_irq_find_parent(np); + if (!parent) + return -ENXIO; + + pctl->domain = irq_find_host(parent); + if (!pctl->domain) + return -ENXIO; + + pctl->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg"); + if (IS_ERR(pctl->regmap)) + return PTR_ERR(pctl->regmap); + + rm = pctl->regmap; + + ret = of_property_read_u32_index(np, "st,syscfg", 1, &offset); + if (ret) + return ret; + + for (i = 0; i < STM32_GPIO_PINS_PER_BANK; i++) { + struct reg_field mux; + + mux.reg = offset + (i / 4) * 4; + mux.lsb = (i % 4) * 4; + mux.msb = mux.lsb + 3; + + pctl->irqmux[i] = devm_regmap_field_alloc(dev, rm, mux); + if (IS_ERR(pctl->irqmux[i])) + return PTR_ERR(pctl->irqmux[i]); + } + + return 0; +} + static int stm32_pctrl_build_state(struct platform_device *pdev) { struct stm32_pinctrl *pctl = platform_get_drvdata(pdev); @@ -823,6 +887,10 @@ int stm32_pctl_probe(struct platform_device *pdev) } } + ret = stm32_pctrl_dt_setup_irq(pdev, pctl); + if (ret) + return ret; + pins = devm_kcalloc(&pdev->dev, pctl->match_data->npins, sizeof(*pins), GFP_KERNEL); if (!pins)