From patchwork Wed Aug 22 20:41:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 144862 Delivered-To: patch@linaro.org Received: by 2002:a2e:164a:0:0:0:0:0 with SMTP id 10-v6csp401778ljw; Wed, 22 Aug 2018 13:41:51 -0700 (PDT) X-Google-Smtp-Source: AA+uWPzFbxYxez7skEB4ORK0UzAqyI5aDn6lcS6vKyxRV7rogdW1ro5n6dGfvC94KKTgfCLSXzxL X-Received: by 2002:a63:af17:: with SMTP id w23-v6mr18772778pge.47.1534970511364; Wed, 22 Aug 2018 13:41:51 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1534970511; cv=none; d=google.com; s=arc-20160816; b=0WByEWeK72O3GBSXDATikIwjZBIzA851846mAF91/Z46C9Zp2EpgnM9zchfc3ZigR9 Di1OpKdPTmNFsD447MGFBgLW0vtxAM2IPXUYpTHIqgu5OUtSRjYkKyzsQCfKccK5ko5t 7u9Dqv+qg6M633tSIe9s7o2/55AJ5h/xi8JrkxpfHvaQH+vfA6TRMaWgzXWL3uwyd4Dc jqG39AErKMirtYQ8xFCOq74p+/F1RaYdgGGakGwxGaybXhzqMESv1gNX2TlUrTI0NMHa PmfTTgCpx5Dbh84/90A2ucc3NKIaS44tArw01akrcg9nLHwWvNxKUiyhA9li5eVKzZfu Hx/A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=3kMzcsDmjehMeekeRJxg79ESOEEpqoYxNeMq7Vevx4U=; b=Mb1oVw/VgsQRAzYI8WLyt1AjKT4n+7QcTMjgV/1jlKgXTnDpThRoh2ZPsl2n7f8T/j QCXvKNWGTHLqBC4SSO/8y1IMgIvV+QsqkDCy2wOroMnPSoi5eFMFMG2dodhWYPeN+aFN e8HJ0I2a0af0X8/r3tEjFmsfh/hLpdJihT/0ngg4vOqpr09R4plHmDHWoEHCDyvBC5eD VieeXN8QHJ3J9gvaX8EKhAfEsCV5QcNXi/8bPF5jytv1+0yF0P0+oJ6aAIReYWKQVXT5 gBptOL5z2Z4tnBtiX8iVBD0NIFmn/90TKObimoRIjVA8fVqJK6ciCa7Tnl01eaeimNct MvRA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=XOzdbpjn; spf=pass (google.com: best guess record for domain of linux-gpio-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-gpio-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id t23-v6si2559068pgi.301.2018.08.22.13.41.51; Wed, 22 Aug 2018 13:41:51 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-gpio-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=XOzdbpjn; spf=pass (google.com: best guess record for domain of linux-gpio-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-gpio-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727596AbeHWAIO (ORCPT + 5 others); Wed, 22 Aug 2018 20:08:14 -0400 Received: from mail-lj1-f193.google.com ([209.85.208.193]:35720 "EHLO mail-lj1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727395AbeHWAIO (ORCPT ); Wed, 22 Aug 2018 20:08:14 -0400 Received: by mail-lj1-f193.google.com with SMTP id p10-v6so2459246ljg.2 for ; Wed, 22 Aug 2018 13:41:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=3kMzcsDmjehMeekeRJxg79ESOEEpqoYxNeMq7Vevx4U=; b=XOzdbpjnNJwsf4eVftb2jgIXiAtMO//8SWCEP7uVAsdBujMXI0N5Fe2FB9PwqfVBJp HpUTL2zq6UERGFggBKcw6qQXCN/n6jAMCrFJGOg6ZxDQ+YMi/CoQLNzJc8GyEoyY6r8H IFXyQ9an0A73QTFEG1naYQRTl0a1SJbDxcapI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=3kMzcsDmjehMeekeRJxg79ESOEEpqoYxNeMq7Vevx4U=; b=XqPS6a6sfv+xssaL4hWnLp/Guxt9FsGc0GGsDpMxYtjFGIBnueq/ez5mGA8TzxbbuW 9NPxaBSAAUcIpq+BpksqaRSJGFHdScu054dsnuv2x5u0xsorPL38SAj7XT7Y1RMzzn8N 2uzDtvJG4/4fHeCeshkOziZweNeEnkP+VGW6wIMMn48ThgqTZvAXEFxytg77+2mzt1h5 BGu0ih+Rdjd5uZvglxvTDJfdyFPnGRLCK06ap19yjkIvS3T369DTzb30Rd+EQDZixJpL 0D0+2NwA8aX5Bg86HK6i07WjapdQdOi76A5cw8uklcSPzBnhzrYRw2MPlXY1kTWvvVBE zhpw== X-Gm-Message-State: AOUpUlFrE1W6RFUKimbPOSIdbKGHEru45h9iqVymVg3NJIbSjM7ZuOzG XRmcy0GLyrNdbEecCB9OVk3gTHptkwjJbQ== X-Received: by 2002:a2e:29da:: with SMTP id p87-v6mr36696887ljp.12.1534970508105; Wed, 22 Aug 2018 13:41:48 -0700 (PDT) Received: from localhost.bredbandsbolaget (c-ae7b71d5.014-348-6c756e10.bbcust.telenor.se. [213.113.123.174]) by smtp.gmail.com with ESMTPSA id q128-v6sm431515ljq.72.2018.08.22.13.41.46 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 22 Aug 2018 13:41:46 -0700 (PDT) From: Linus Walleij To: H Hartley Sweeten , Alexander Sverdlin Cc: linux-arm-kernel@lists.infradead.org, linux-gpio@vger.kernel.org, Linus Walleij Subject: [PATCH 11/11] gpio: ep93xx: Switch A and B to use GPIOLIB_IRQCHIP Date: Wed, 22 Aug 2018 22:41:11 +0200 Message-Id: <20180822204111.9581-12-linus.walleij@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180822204111.9581-1-linus.walleij@linaro.org> References: <20180822204111.9581-1-linus.walleij@linaro.org> Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org We can quite easily switch banks/ports A and B to use GPIOLIB_IRQCHIP which is code that will be more careful about handling interrupt descriptors and use a proper irqdomain for translating the IRQs. This cuts down some code in favor of using the implementation inside gpiolib. Signed-off-by: Linus Walleij --- drivers/gpio/Kconfig | 1 + drivers/gpio/gpio-ep93xx.c | 95 ++++++++++++++++++++------------------ 2 files changed, 51 insertions(+), 45 deletions(-) -- 2.17.1 diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 71c0ab46f216..afcd94613017 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -200,6 +200,7 @@ config GPIO_EP93XX def_bool y depends on ARCH_EP93XX select GPIO_GENERIC + select GPIOLIB_IRQCHIP config GPIO_EXAR tristate "Support for GPIO pins on XR17V352/354/358" diff --git a/drivers/gpio/gpio-ep93xx.c b/drivers/gpio/gpio-ep93xx.c index d45d8ac3b525..68a416fc3141 100644 --- a/drivers/gpio/gpio-ep93xx.c +++ b/drivers/gpio/gpio-ep93xx.c @@ -29,13 +29,10 @@ #define EP93XX_GPIO_LINE_MAX_IRQ 23 /* - * IRQ numbers used by this driver is 64 ..87 - * - * Map GPIO A0..A7 (0..7) to irq 64..71, - * B0..B7 (7..15) to irq 72..79, and - * F0..F7 (16..24) to irq 80..87. + * Static mapping of GPIO bank F IRQS: + * F0..F7 (16..24) to irq 80..87. */ -static unsigned int ep93xx_gpio_irq_base[3] = { 64, 72, 80 }; +#define EP93XX_GPIO_F_IRQ_BASE 80 struct ep93xx_gpio { void __iomem *base; @@ -117,17 +114,21 @@ static void ep93xx_gpio_ab_irq_handler(struct irq_desc *desc) chained_irq_enter(irqchip, desc); + /* + * Dispatch the IRQs to the irqdomain of each A and B + * gpiochip irqdomains depending on what has fired. + * The tricky part is that the IRQ line is shared + * between bank A and B and each has their own gpiochip. + */ stat = readb(epg->base + EP93XX_GPIO_A_INT_STATUS); - for_each_set_bit(offset, &stat, 8) { - int gpio_irq = ep93xx_gpio_irq_base[0] + offset; - generic_handle_irq(gpio_irq); - } + for_each_set_bit(offset, &stat, 8) + generic_handle_irq(irq_find_mapping(epg->gc[0].irq.domain, + offset)); stat = readb(epg->base + EP93XX_GPIO_B_INT_STATUS); - for_each_set_bit(offset, &stat, 8) { - int gpio_irq = ep93xx_gpio_irq_base[1] + offset; - generic_handle_irq(gpio_irq); - } + for_each_set_bit(offset, &stat, 8) + generic_handle_irq(irq_find_mapping(epg->gc[1].irq.domain, + offset)); chained_irq_exit(irqchip, desc); } @@ -142,7 +143,7 @@ static void ep93xx_gpio_f_irq_handler(struct irq_desc *desc) struct irq_chip *irqchip = irq_desc_get_chip(desc); unsigned int irq = irq_desc_get_irq(desc); int port_f_idx = ((irq + 1) & 7) ^ 4; /* {19..22,47..50} -> {0..7} */ - int gpio_irq = ep93xx_gpio_irq_base[2] + port_f_idx; + int gpio_irq = EP93XX_GPIO_F_IRQ_BASE + port_f_idx; chained_irq_enter(irqchip, desc); generic_handle_irq(gpio_irq); @@ -268,44 +269,53 @@ static struct irq_chip ep93xx_gpio_irq_chip = { .irq_set_type = ep93xx_gpio_irq_type, }; -static void ep93xx_gpio_init_irq(struct platform_device *pdev, - struct ep93xx_gpio *epg) +static int ep93xx_gpio_init_irq(struct platform_device *pdev, + struct ep93xx_gpio *epg) { + int ab_parent_irq = platform_get_irq(pdev, 0); + struct device *dev = &pdev->dev; int gpio_irq; + int ret; int i; /* The A bank */ - for (i = 0; i < 8; i++) { - gpio_irq = ep93xx_gpio_irq_base[0] + i; - irq_set_chip_data(gpio_irq, &epg->gc[0]); - irq_set_chip_and_handler(gpio_irq, &ep93xx_gpio_irq_chip, - handle_level_irq); - irq_clear_status_flags(gpio_irq, IRQ_NOREQUEST); + ret = gpiochip_irqchip_add(&epg->gc[0], &ep93xx_gpio_irq_chip, + 64, handle_level_irq, + IRQ_TYPE_NONE); + if (ret) { + dev_err(dev, "Could not add irqchip 0\n"); + return ret; } + gpiochip_set_chained_irqchip(&epg->gc[0], &ep93xx_gpio_irq_chip, + ab_parent_irq, + ep93xx_gpio_ab_irq_handler); + /* The B bank */ - for (i = 0; i < 8; i++) { - gpio_irq = ep93xx_gpio_irq_base[1] + i; - irq_set_chip_data(gpio_irq, &epg->gc[1]); - irq_set_chip_and_handler(gpio_irq, &ep93xx_gpio_irq_chip, - handle_level_irq); - irq_clear_status_flags(gpio_irq, IRQ_NOREQUEST); + ret = gpiochip_irqchip_add(&epg->gc[1], &ep93xx_gpio_irq_chip, + 72, handle_level_irq, + IRQ_TYPE_NONE); + if (ret) { + dev_err(dev, "Could not add irqchip 1\n"); + return ret; } + gpiochip_set_chained_irqchip(&epg->gc[1], &ep93xx_gpio_irq_chip, + ab_parent_irq, + ep93xx_gpio_ab_irq_handler); + /* The F bank */ for (i = 0; i < 8; i++) { - gpio_irq = ep93xx_gpio_irq_base[2] + i; + gpio_irq = EP93XX_GPIO_F_IRQ_BASE + i; irq_set_chip_data(gpio_irq, &epg->gc[5]); irq_set_chip_and_handler(gpio_irq, &ep93xx_gpio_irq_chip, handle_level_irq); irq_clear_status_flags(gpio_irq, IRQ_NOREQUEST); } - irq_set_chained_handler_and_data(platform_get_irq(pdev, 0), - ep93xx_gpio_ab_irq_handler, - &epg->gc[0]); for (i = 1; i <= 8; i++) irq_set_chained_handler_and_data(platform_get_irq(pdev, i), ep93xx_gpio_f_irq_handler, &epg->gc[i]); + return 0; } @@ -354,15 +364,9 @@ static int ep93xx_gpio_set_config(struct gpio_chip *gc, unsigned offset, return 0; } -static int ep93xx_gpio_to_irq(struct gpio_chip *gc, unsigned offset) +static int ep93xx_gpio_f_to_irq(struct gpio_chip *gc, unsigned offset) { - int port = ep93xx_gpio_port(gc); - - /* Those are the ports supporting IRQ */ - if (port != 0 && port != 1 && port != 5) - return -EINVAL; - - return ep93xx_gpio_irq_base[port] + offset; + return EP93XX_GPIO_F_IRQ_BASE + offset; } static int ep93xx_gpio_add_bank(struct gpio_chip *gc, struct device *dev, @@ -380,10 +384,8 @@ static int ep93xx_gpio_add_bank(struct gpio_chip *gc, struct device *dev, gc->label = bank->label; gc->base = bank->base; - if (bank->has_irq) { + if (bank->has_irq) gc->set_config = ep93xx_gpio_set_config; - gc->to_irq = ep93xx_gpio_to_irq; - } return devm_gpiochip_add_data(dev, gc, epg); } @@ -410,7 +412,10 @@ static int ep93xx_gpio_probe(struct platform_device *pdev) if (ep93xx_gpio_add_bank(gc, &pdev->dev, epg, bank)) dev_warn(&pdev->dev, "Unable to add gpio bank %s\n", - bank->label); + bank->label); + /* Only bank F has especially funky IRQ handling */ + if (i == 5) + gc->to_irq = ep93xx_gpio_f_to_irq; } ep93xx_gpio_init_irq(pdev, epg);