From patchwork Thu Mar 31 15:09:36 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Coquelin X-Patchwork-Id: 8714241 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 7966C9F44D for ; Thu, 31 Mar 2016 15:13:34 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 7E35720251 for ; Thu, 31 Mar 2016 15:13:33 +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 910FA20272 for ; Thu, 31 Mar 2016 15:13:32 +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 1aleGC-0001QK-A2; Thu, 31 Mar 2016 15:11:48 +0000 Received: from mail-wm0-x244.google.com ([2a00:1450:400c:c09::244]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1aleEc-0007WU-U3 for linux-arm-kernel@lists.infradead.org; Thu, 31 Mar 2016 15:10:14 +0000 Received: by mail-wm0-x244.google.com with SMTP id p65so24481843wmp.1 for ; Thu, 31 Mar 2016 08:09:54 -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=hFeoSfqH87nM48ZzQxc9M48VNm9wLa2O70RiEh1af8Q=; b=d3MGgOUjCGmJzX/eGjMeSZb3torQGo86cYR6ncoTHOplgEWkXxbtDIsyn8e/AL6EgN uGR/bQlu/VYvj+rTCmHPxVkJ/pjwHWyjB6xFudy9brA9LWbfNz33Cy8+3zhFxap3gZVe q4NiCzt8n+7XpOcM609SzYz1REmdVpsjrB3PIvd/lnanHW65Q7UhM6aYAh69griGL/4z 0A36anzwyYv8YQh9ZDzzAeKBDesijvYV6J+pEdpjsyGqIdhpbkmdGqgOvbuYbyeknHN5 6ybCfceVfhxXieNK+/QBP6D16rCI8MhKk2QVfFwaSrIFAbTvFIwoFf0jRGm1Qs0RjJyv DhJQ== 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=hFeoSfqH87nM48ZzQxc9M48VNm9wLa2O70RiEh1af8Q=; b=bdz+pVP4YdiXquu6CXqV8IM7sqAvgWOg+3lJkMRm8baPRbOwg1gVlgmMYYBK6NEvKG smph95oKxxaDMZ2I+j4A+Ct3aMtcMl7aZOP5xP90U0w0yl2xmajJvdtNHucLPGltIW7H 4diLEtGnHZK9RLvTffRxGzh6ocdlreg3Hx5LqU32oMkVqr8t5uw0/v1nB3fqNdvXuB5W sdxOQANC+rftjQjnyll3pq3DOxbWUbbG9IcEIXDeBpn7ymveAzUm+s2BUwgvPBhsIpZT i4+jFxM/GD0KP6EVTBQiqhOGWVVFrMKHoyBeRqFlD78aOJ/CtBHR/ZFv0bu0EPSyhC/k rJxA== X-Gm-Message-State: AD7BkJIBWi21D0a3FMi0dUqvQxR6xc7KNhPktynU1+D7Rb0sBAdbpPaIpbdr3EG/etg1pQ== X-Received: by 10.28.104.131 with SMTP id d125mr303691wmc.99.1459436993106; Thu, 31 Mar 2016 08:09:53 -0700 (PDT) Received: from lmecul0520.st.com. (241.204.154.77.rev.sfr.net. [77.154.204.241]) by smtp.gmail.com with ESMTPSA id i5sm9505781wjx.15.2016.03.31.08.09.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 31 Mar 2016 08:09:52 -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 v2 6/9] pinctrl: Add IRQ support to STM32 gpios Date: Thu, 31 Mar 2016 17:09:36 +0200 Message-Id: <1459436979-17275-7-git-send-email-mcoquelin.stm32@gmail.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1459436979-17275-1-git-send-email-mcoquelin.stm32@gmail.com> References: <1459436979-17275-1-git-send-email-mcoquelin.stm32@gmail.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160331_081011_281719_898FB479 X-CRM114-Status: GOOD ( 19.11 ) 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, lee.jones@linaro.org, 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=-5.1 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, T_DKIM_INVALID, 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 0f28841b2332..b5cac5bfd0cd 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 8deb566ed4cd..f2fa717894dc 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 @@ -77,6 +80,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) @@ -174,6 +180,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->parent); + struct stm32_gpio_bank *bank = gpiochip_get_data(chip); + unsigned int irq; + + regmap_field_write(pctl->irqmux[offset], bank->range.id); + + irq = irq_create_mapping(pctl->domain, offset); + if (!irq) + return -ENXIO; + + return irq; +} + static struct gpio_chip stm32_gpio_template = { .request = stm32_gpio_request, .free = stm32_gpio_free, @@ -181,6 +203,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 */ @@ -704,6 +727,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); @@ -796,6 +860,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)