From patchwork Wed Oct 19 15:37:44 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jerome Brunet X-Patchwork-Id: 684204 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3szbhc1qkQz9vGn for ; Thu, 20 Oct 2016 02:39:12 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=baylibre-com.20150623.gappssmtp.com header.i=@baylibre-com.20150623.gappssmtp.com header.b=HvWxaUcR; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S945415AbcJSPhy (ORCPT ); Wed, 19 Oct 2016 11:37:54 -0400 Received: from mail-qk0-f174.google.com ([209.85.220.174]:33819 "EHLO mail-qk0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S945249AbcJSPhw (ORCPT ); Wed, 19 Oct 2016 11:37:52 -0400 Received: by mail-qk0-f174.google.com with SMTP id f128so40156381qkb.1 for ; Wed, 19 Oct 2016 08:37:52 -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=WrfGcU8Oca2BK0+HLJmef1NnzE9DGhYiRO78+BU8oPw=; b=HvWxaUcRMJ7RzrB1qLBzapAd/lBpG2t8/7OHcu4qWazIuqbUXe8rbcVqKoRwj6FJ9H Cfb+KUYFLrEzVHGZosr4Ny5bqwTbJ+z4Ud385rnYZwkmzndO2ClKqAPe7y3t933Ai/kk dfQfMiSqPaORiCZ1bMDyVfvF/KlFr7Ks+9nEadQdccQSxBfX9/JPUG7nP3jyro+fIeRr nrJSYowQwE666LLo2rKo5FCdeleis/X9yKW/rYFJe3HOZLGSkxdWjMCOWBDCBhit0ftE JfK5cqHgVKZypmUT9P7XhivsADmY4H8Au3ikIYAu5kdaKKz9IhkaNCLxzk/fklQM2nXt O7NQ== 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=WrfGcU8Oca2BK0+HLJmef1NnzE9DGhYiRO78+BU8oPw=; b=mQNTxQK9fJjD2qjhwqemt4RqIQQ4dGC5uicL930neYm1FfeCfp1ju/fb6wViB6uKiY Jy8oPvsMvPIyVjVTSOBixqbAjsxKpOD1QfkZ2DExdff+BE8OFoZn6eG77BSDBrZBhGHj Z806Op5TGmxT3LgNXJxe37TJHqTmONaBMPp+jf297ZLm4DRe9tLLxZGx1RIPhGzusS9T 9pAnEjS9ZqBy9m+ztMk8tDfCHdVD+X7KbgZImNS6tr9JtkcwaQ5KOgYECeLyIEWWaVK1 l7I1D5gthhbRTC+YTUbl5qrzVGv/2eu6XQnOVL19L9w6sA3cImIJmfdnrdNtu6FKugm/ nUpg== X-Gm-Message-State: AA6/9RlaYu2wxgd0X9xM3NoxmHcxu7aXh24nlcuveijWR/RnhJZse3w799+av2CWyWoj0D0m X-Received: by 10.194.103.165 with SMTP id fx5mr4627472wjb.188.1476891470182; Wed, 19 Oct 2016 08:37:50 -0700 (PDT) Received: from boomer.baylibre.com ([90.63.244.31]) by smtp.googlemail.com with ESMTPSA id vx1sm36601256wjc.3.2016.10.19.08.37.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 19 Oct 2016 08:37:49 -0700 (PDT) From: Jerome Brunet To: Carlo Caione , Kevin Hilman , Linus Walleij Cc: Jerome Brunet , linux-amlogic@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Thomas Gleixner , Jason Cooper , Marc Zyngier , Rob Herring , Catalin Marinas , Will Deacon , Russell King Subject: [RESEND PATCH v2 4/9] pinctrl: meson: allow gpio to request irq Date: Wed, 19 Oct 2016 17:37:44 +0200 Message-Id: <1476891464-11564-1-git-send-email-jbrunet@baylibre.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1476890480-8884-5-git-send-email-jbrunet@baylibre.com> References: <1476890480-8884-5-git-send-email-jbrunet@baylibre.com> Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org 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 --- I messed up in v2 and actually sent the v1 again. Here is the actual v2 with the fix. Again, sorry for the inconvenience. drivers/pinctrl/Kconfig | 2 + drivers/pinctrl/meson/pinctrl-meson.c | 69 +++++++++++++++++++++++++++++++++++ drivers/pinctrl/meson/pinctrl-meson.h | 1 + 3 files changed, 72 insertions(+) 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..e3f5241f337f 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,19 @@ static struct regmap *meson_map_resource(struct meson_pinctrl *pc, return devm_regmap_init_mmio(pc->dev, base, &meson_regmap_config); } +static void meson_pinctrl_get_irq_gpio_intc(struct meson_pinctrl *pc, + struct device_node *node) +{ + struct device_node *np = of_irq_find_parent(node); + + if (!np || !of_device_is_compatible(np, pc->data->irq_compat)) { + dev_info(pc->dev, "gpio interrupt disabled\n"); + pc->fwnode = NULL; + } else { + pc->fwnode = of_node_to_fwnode(np); + } +} + static int meson_pinctrl_parse_dt(struct meson_pinctrl *pc, struct device_node *node) { @@ -643,6 +710,8 @@ static int meson_pinctrl_parse_dt(struct meson_pinctrl *pc, return PTR_ERR(pc->reg_gpio); } + meson_pinctrl_get_irq_gpio_intc(pc, gpio_np); + return 0; } 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)