From patchwork Fri Sep 1 18:57:21 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Reding X-Patchwork-Id: 808978 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Yz7J19VJ"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3xkTCS54m6z9sQl for ; Sat, 2 Sep 2017 05:03:00 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752673AbdIATB6 (ORCPT ); Fri, 1 Sep 2017 15:01:58 -0400 Received: from mail-wr0-f193.google.com ([209.85.128.193]:37297 "EHLO mail-wr0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752131AbdIAS5l (ORCPT ); Fri, 1 Sep 2017 14:57:41 -0400 Received: by mail-wr0-f193.google.com with SMTP id k9so478847wre.4; Fri, 01 Sep 2017 11:57:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Qn0BJh7I5Jze/UnGirJwTdrrxm7wrr/Bm28c51H/3TQ=; b=Yz7J19VJ9dko/ksG7AGDE8dQPVNNpTmf6zGeI4D2QxElvzgWnpknheyptRhLVZM1EJ L6dZywJMQmeQyncXPaKHAtyWNRDz/r/91UFIGO6VCJQBE47583MfijJsjPA4Czp+/DDU 2WIQ2CviFITw7d8L9bYoampXebwn+BQBozjxuSyjCdwKVXJ72bSIwWwPgoSmCfBHmkCQ TXqxSbgnq7j2OV7QODjrw4kGLecTgmteWX+v8x38wXCsNgUsL3o3t7l2UP6rcnMr4H0H MHBBAkq03e0cib0XuC+ab2pYq3pP5vk3gZXzj9BvF1P5Y+E+cJJ7eHA1jhzNiSqcvULT l7Tg== 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=Qn0BJh7I5Jze/UnGirJwTdrrxm7wrr/Bm28c51H/3TQ=; b=N7aczZcjOZtJdAL/boOitrtfZjGaRR+/7jC25uKBd2rbsMYUE32V/UNkNZTSeWzArx NtZ4MieCvcu5uqnB5wzxF7XwuDQRvjQCbU3pj6fSzoeaCO2AMVJFcGHGjTzKUqn/V05+ Xl1i/CX9MCuJCCtOXqPQADnGzLuhi5L+htMnMffdH6sg5Hkg7ehs+y4k4qXyh6tU4QTv El/CTc5BC0dnCg7q33hFUI0gUmZu/hz1ZaEZ+0vo9N9i4EOOEhllryn3bVSUCakeUxE4 HRkzvNwqCuHTz2RtXtfpx9FTrVRFoZsriLxVdEHJyk0dCA4Bvd1OMc6RVuu4W9Q2vDPg BirQ== X-Gm-Message-State: AHPjjUjtJ8ajmA73g1znWVJgmigw7Y/MJKWHv6VIJ2w1veFdaMQYTrAW GLTIyXJrVlIizA== X-Google-Smtp-Source: ADKCNb5A9kfOfzYTI+Hkw9YznpiKOnXmff6asoXMJc+VwYfnPf5k2xbvZnwCoC0nv4dk1cun4gIRkw== X-Received: by 10.223.155.209 with SMTP id e17mr2068599wrc.298.1504292259953; Fri, 01 Sep 2017 11:57:39 -0700 (PDT) Received: from localhost (p200300E41BD6D60076D02BFFFE273F51.dip0.t-ipconnect.de. [2003:e4:1bd6:d600:76d0:2bff:fe27:3f51]) by smtp.gmail.com with ESMTPSA id p105sm907998wrc.64.2017.09.01.11.57.38 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 01 Sep 2017 11:57:38 -0700 (PDT) From: Thierry Reding To: Linus Walleij Cc: Jonathan Hunter , linux-gpio@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 01/16] gpio: Implement tighter IRQ chip integration Date: Fri, 1 Sep 2017 20:57:21 +0200 Message-Id: <20170901185736.28051-2-thierry.reding@gmail.com> X-Mailer: git-send-email 2.13.3 In-Reply-To: <20170901185736.28051-1-thierry.reding@gmail.com> References: <20170901185736.28051-1-thierry.reding@gmail.com> Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Thierry Reding Currently GPIO drivers are required to a GPIO chip and the corresponding IRQ chip separately, which can result in a lot of boilerplate. Introduce a new struct gpio_irq_chip, embedded in a struct gpio_chip, that drivers can fill in if they want the GPIO core to automatically register the IRQ chip associated with a GPIO chip. Signed-off-by: Thierry Reding --- drivers/gpio/gpiolib.c | 146 +++++++++++++++++++++++++++++++++++++++++++- include/linux/gpio/driver.h | 64 +++++++++++++++++++ 2 files changed, 207 insertions(+), 3 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 18bba1748a35..abc0f72e9950 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -72,6 +72,7 @@ static LIST_HEAD(gpio_lookup_list); LIST_HEAD(gpio_devices); static void gpiochip_free_hogs(struct gpio_chip *chip); +static int gpiochip_add_irqchip(struct gpio_chip *gpiochip); static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip); static int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gpiochip); static void gpiochip_irqchip_free_valid_mask(struct gpio_chip *gpiochip); @@ -1271,6 +1272,10 @@ int gpiochip_add_data(struct gpio_chip *chip, void *data) if (status) goto err_remove_from_list; + status = gpiochip_add_irqchip(chip); + if (status) + goto err_remove_chip; + status = of_gpiochip_add(chip); if (status) goto err_remove_chip; @@ -1637,8 +1642,8 @@ EXPORT_SYMBOL_GPL(gpiochip_set_nested_irqchip); * gpiochip by assigning the gpiochip as chip data, and using the irqchip * stored inside the gpiochip. */ -static int gpiochip_irq_map(struct irq_domain *d, unsigned int irq, - irq_hw_number_t hwirq) +int gpiochip_irq_map(struct irq_domain *d, unsigned int irq, + irq_hw_number_t hwirq) { struct gpio_chip *chip = d->host_data; @@ -1666,8 +1671,9 @@ static int gpiochip_irq_map(struct irq_domain *d, unsigned int irq, return 0; } +EXPORT_SYMBOL_GPL(gpiochip_irq_map); -static void gpiochip_irq_unmap(struct irq_domain *d, unsigned int irq) +void gpiochip_irq_unmap(struct irq_domain *d, unsigned int irq) { struct gpio_chip *chip = d->host_data; @@ -1676,6 +1682,7 @@ static void gpiochip_irq_unmap(struct irq_domain *d, unsigned int irq) irq_set_chip_and_handler(irq, NULL, NULL); irq_set_chip_data(irq, NULL); } +EXPORT_SYMBOL_GPL(gpiochip_irq_unmap); static const struct irq_domain_ops gpiochip_domain_ops = { .map = gpiochip_irq_map, @@ -1717,6 +1724,124 @@ static int gpiochip_to_irq(struct gpio_chip *chip, unsigned offset) } /** + * gpiochip_add_irqchip() - adds an IRQ chip to a GPIO chip + * @gpiochip: the GPIO chip to add the IRQ chip to + */ +static int gpiochip_add_irqchip(struct gpio_chip *gpiochip) +{ + struct irq_chip *irqchip = gpiochip->irqchip; + const struct irq_domain_ops *ops; + struct device_node *np; + unsigned int type; + unsigned int i; + + if (!irqchip) + return 0; + + if (gpiochip->irq.parent_handler && gpiochip->can_sleep) { + chip_err(gpiochip, "you cannot have chained interrupts on a " + "chip that may sleep\n"); + return -EINVAL; + } + + type = gpiochip->irq_default_type; + np = gpiochip->parent->of_node; + +#ifdef CONFIG_OF_GPIO + /* + * If the gpiochip has an assigned OF node this takes precedence + * FIXME: get rid of this and use gpiochip->parent->of_node + * everywhere + */ + if (gpiochip->of_node) + np = gpiochip->of_node; +#endif + + /* + * Specifying a default trigger is a terrible idea if DT or ACPI is + * used to configure the interrupts, as you may end up with + * conflicting triggers. Tell the user, and reset to NONE. + */ + if (WARN(np && type != IRQ_TYPE_NONE, + "%s: Ignoring %u default trigger\n", np->full_name, type)) + type = IRQ_TYPE_NONE; + + if (has_acpi_companion(gpiochip->parent) && type != IRQ_TYPE_NONE) { + acpi_handle_warn(ACPI_HANDLE(gpiochip->parent), + "Ignoring %u default trigger\n", type); + type = IRQ_TYPE_NONE; + } + + gpiochip->to_irq = gpiochip_to_irq; + gpiochip->irq_default_type = type; + + if (gpiochip->irq.domain_ops) + ops = gpiochip->irq.domain_ops; + else + ops = &gpiochip_domain_ops; + + gpiochip->irqdomain = irq_domain_add_simple(np, gpiochip->ngpio, + gpiochip->irq_base, + ops, gpiochip); + if (!gpiochip->irqdomain) + return -EINVAL; + + /* + * It is possible for a driver to override this, but only if the + * alternative functions are both implemented. + */ + if (!irqchip->irq_request_resources && + !irqchip->irq_release_resources) { + irqchip->irq_request_resources = gpiochip_irq_reqres; + irqchip->irq_release_resources = gpiochip_irq_relres; + } + + if (gpiochip->irq.parent_handler) { + void *data = gpiochip->irq.parent_handler_data ?: gpiochip; + + for (i = 0; i < gpiochip->irq.num_parents; i++) { + /* + * The parent IRQ chip is already using the chip_data + * for this IRQ chip, so our callbacks simply use the + * handler_data. + */ + irq_set_chained_handler_and_data(gpiochip->irq.parents[i], + gpiochip->irq.parent_handler, + data); + } + + gpiochip->irq_nested = false; + } else { + gpiochip->irq_nested = true; + } + + /* + * Prepare the mapping since the IRQ chip shall be orthogonal to any + * GPIO chip calls. + */ + for (i = 0; i < gpiochip->ngpio; i++) { + unsigned int irq; + + if (!gpiochip_irqchip_irq_valid(gpiochip, i)) + continue; + + irq = irq_create_mapping(gpiochip->irqdomain, i); + if (!irq) { + chip_err(gpiochip, + "failed to create IRQ mapping for GPIO#%u\n", + i); + continue; + } + + irq_set_parent(irq, gpiochip->irq.map[i]); + } + + acpi_gpiochip_request_interrupts(gpiochip); + + return 0; +} + +/** * gpiochip_irqchip_remove() - removes an irqchip added to a gpiochip * @gpiochip: the gpiochip to remove the irqchip from * @@ -1733,6 +1858,16 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip) irq_set_handler_data(gpiochip->irq_chained_parent, NULL); } + if (gpiochip->irqchip) { + struct gpio_irq_chip *irq = &gpiochip->irq; + unsigned int i; + + for (i = 0; i < irq->num_parents; i++) { + irq_set_chained_handler(irq->parents[i], NULL); + irq_set_handler_data(irq->parents[i], NULL); + } + } + /* Remove all IRQ mappings and delete the domain */ if (gpiochip->irqdomain) { for (offset = 0; offset < gpiochip->ngpio; offset++) { @@ -1853,6 +1988,11 @@ EXPORT_SYMBOL_GPL(gpiochip_irqchip_add_key); #else /* CONFIG_GPIOLIB_IRQCHIP */ +static inline int gpiochip_add_irqchip(struct gpio_chip *gpiochip) +{ + return 0; +} + static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip) {} static inline int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gpiochip) { diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index c97f8325e8bf..6100b171817e 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -19,6 +19,58 @@ struct module; #ifdef CONFIG_GPIOLIB +#ifdef CONFIG_GPIOLIB_IRQCHIP +/** + * struct gpio_irq_chip - GPIO interrupt controller + */ +struct gpio_irq_chip { + /** + * @domain_ops: + * + * Table of interrupt domain operations for this IRQ chip. + */ + const struct irq_domain_ops *domain_ops; + + /** + * @parent_handler: + * + * The interrupt handler for the GPIO chip's parent interrupts, may be + * NULL if the parent interrupts are nested rather than cascaded. + */ + irq_flow_handler_t parent_handler; + + /** + * @parent_handler_data: + * + * Data associated, and passed to, the handler for the parent + * interrupt. + */ + void *parent_handler_data; + + /** + * @num_parents: + * + * The number of interrupt parents of a GPIO chip. + */ + unsigned int num_parents; + + /** + * @parents: + * + * A list of interrupt parents of a GPIO chip. This is owned by the + * driver, so the core will only reference this list, not modify it. + */ + unsigned int *parents; + + /** + * @map: + * + * A list of interrupt parents for each line of a GPIO chip. + */ + unsigned int *map; +}; +#endif + /** * struct gpio_chip - abstract a GPIO controller * @label: a functional name for the GPIO device, such as a part @@ -173,6 +225,14 @@ struct gpio_chip { bool irq_need_valid_mask; unsigned long *irq_valid_mask; struct lock_class_key *lock_key; + + /** + * @irq: + * + * Integrates interrupt chip functionality with the GPIO chip. Can be + * used to handle IRQs for most practical cases. + */ + struct gpio_irq_chip irq; #endif #if defined(CONFIG_OF_GPIO) @@ -264,6 +324,10 @@ int bgpio_init(struct gpio_chip *gc, struct device *dev, #ifdef CONFIG_GPIOLIB_IRQCHIP +int gpiochip_irq_map(struct irq_domain *d, unsigned int irq, + irq_hw_number_t hwirq); +void gpiochip_irq_unmap(struct irq_domain *d, unsigned int irq); + void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip, struct irq_chip *irqchip, unsigned int parent_irq, From patchwork Fri Sep 1 18:57:22 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Reding X-Patchwork-Id: 808974 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="mNLaFh1e"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3xkTC85mf0z9sQl for ; Sat, 2 Sep 2017 05:02:35 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752371AbdIAS5q (ORCPT ); Fri, 1 Sep 2017 14:57:46 -0400 Received: from mail-wm0-f66.google.com ([74.125.82.66]:37020 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752327AbdIAS5n (ORCPT ); Fri, 1 Sep 2017 14:57:43 -0400 Received: by mail-wm0-f66.google.com with SMTP id x189so953259wmg.4; Fri, 01 Sep 2017 11:57:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=pwt9NqqDygjIyVg0Beg8bhmsbCPHoTn2TPDBvd6YF6E=; b=mNLaFh1ed/RcT5z4tDEQnNAM0GflySY8Uy8BHLJiRlMI+ktPEMSFFiu3LgmkAAal8L FfGqd6LKPdTaz6GEMwp8g3xPZ9E+X2rYD+fErM4lVM6domXp6A/tRdi3nAue5xBs8tJ2 NItVTZvFWub4Egah78UzOP8ryrtY4AdFsZV3J8CPY8CFg+YjJbxESvBJ/6YoMH6BADEJ Q1tgjmyYhpBZRAz+jc6HvlOA8Np15/DzwGw+qgAu82Nn37UT0KSgFyXf8Ol0MHGe1xVv OBw3cDJSBJ2Z19yAC5bxomv4UcZAMKxXVJJjlaJATIFfv9oqg0MJcvv6Ru4s27d+wZdN VKOg== 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=pwt9NqqDygjIyVg0Beg8bhmsbCPHoTn2TPDBvd6YF6E=; b=LnU1XFgpDZc1uV3ZysCwx4vDrrOE9j1I37rV3ZMJQPiS9Oy4ut5CKkTCFUdV6JEuW5 cerES/Ke8ZQp5kfgZaIH+oQZciTrpWKF72BSPkzRp56X/t65rWOG2WRYL+FYn4kLOs6a dy/zHECUF/APwI8L0YFG1wmkkMMGLCWNnvLqB7kmEfXf/eEJWFs4K7t+pyDSFBepXuHe E1401HXMvPpdDb/bgNQINWL5mnAuOG3fUCMj/BMN/FMt5RUInbbFa5OcOhkxZl9P6rWE o9zGsYGXckajnGHl8XSfvaQmjCeVeBeudts/G44EJcW8KNEbQDeyu5RF55B55UrC6htM aRfw== X-Gm-Message-State: AHPjjUh3TXoGBMBpSGeS4sHU+JX8ngmbF7vCc+N++RniOAZuABMk0HaO E+/ZJiEC/VhkxA== X-Google-Smtp-Source: ADKCNb5bCwryWAKgiRULYBPLoOtPeAaSaN1F/QPXlTTejmLkXZ5yqwKwCOEZO5m1MHl82Q/3mxh62A== X-Received: by 10.28.140.196 with SMTP id o187mr1278056wmd.160.1504292261649; Fri, 01 Sep 2017 11:57:41 -0700 (PDT) Received: from localhost (p200300E41BD6D60076D02BFFFE273F51.dip0.t-ipconnect.de. [2003:e4:1bd6:d600:76d0:2bff:fe27:3f51]) by smtp.gmail.com with ESMTPSA id u22sm576634wrf.15.2017.09.01.11.57.40 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 01 Sep 2017 11:57:40 -0700 (PDT) From: Thierry Reding To: Linus Walleij Cc: Jonathan Hunter , linux-gpio@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 02/16] gpio: Move irqchip into struct gpio_irq_chip Date: Fri, 1 Sep 2017 20:57:22 +0200 Message-Id: <20170901185736.28051-3-thierry.reding@gmail.com> X-Mailer: git-send-email 2.13.3 In-Reply-To: <20170901185736.28051-1-thierry.reding@gmail.com> References: <20170901185736.28051-1-thierry.reding@gmail.com> Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Thierry Reding In order to consolidate the multiple ways to associate an IRQ chip with a GPIO chip, move more fields into the new struct gpio_irq_chip. Signed-off-by: Thierry Reding --- drivers/gpio/gpiolib.c | 18 +++++++++--------- include/linux/gpio/driver.h | 14 ++++++++++++-- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index abc0f72e9950..4058adde7dc6 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1656,7 +1656,7 @@ int gpiochip_irq_map(struct irq_domain *d, unsigned int irq, * category than their parents, so it won't report false recursion. */ irq_set_lockdep_class(irq, chip->lock_key); - irq_set_chip_and_handler(irq, chip->irqchip, chip->irq_handler); + irq_set_chip_and_handler(irq, chip->irq.chip, chip->irq_handler); /* Chips that use nested thread handlers have them marked */ if (chip->irq_nested) irq_set_nested_thread(irq, 1); @@ -1729,7 +1729,7 @@ static int gpiochip_to_irq(struct gpio_chip *chip, unsigned offset) */ static int gpiochip_add_irqchip(struct gpio_chip *gpiochip) { - struct irq_chip *irqchip = gpiochip->irqchip; + struct irq_chip *irqchip = gpiochip->irq.chip; const struct irq_domain_ops *ops; struct device_node *np; unsigned int type; @@ -1858,7 +1858,7 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip) irq_set_handler_data(gpiochip->irq_chained_parent, NULL); } - if (gpiochip->irqchip) { + if (gpiochip->irq.chip) { struct gpio_irq_chip *irq = &gpiochip->irq; unsigned int i; @@ -1879,10 +1879,10 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip) irq_domain_remove(gpiochip->irqdomain); } - if (gpiochip->irqchip) { - gpiochip->irqchip->irq_request_resources = NULL; - gpiochip->irqchip->irq_release_resources = NULL; - gpiochip->irqchip = NULL; + if (gpiochip->irq.chip) { + gpiochip->irq.chip->irq_request_resources = NULL; + gpiochip->irq.chip->irq_release_resources = NULL; + gpiochip->irq.chip = NULL; } gpiochip_irqchip_free_valid_mask(gpiochip); @@ -1957,7 +1957,7 @@ int gpiochip_irqchip_add_key(struct gpio_chip *gpiochip, type = IRQ_TYPE_NONE; } - gpiochip->irqchip = irqchip; + gpiochip->irq.chip = irqchip; gpiochip->irq_handler = handler; gpiochip->irq_default_type = type; gpiochip->to_irq = gpiochip_to_irq; @@ -1966,7 +1966,7 @@ int gpiochip_irqchip_add_key(struct gpio_chip *gpiochip, gpiochip->ngpio, first_irq, &gpiochip_domain_ops, gpiochip); if (!gpiochip->irqdomain) { - gpiochip->irqchip = NULL; + gpiochip->irq.chip = NULL; return -EINVAL; } diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 6100b171817e..974247646886 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -25,6 +25,13 @@ struct module; */ struct gpio_irq_chip { /** + * @chip: + * + * GPIO IRQ chip implementation, provided by GPIO driver. + */ + struct irq_chip *chip; + + /** * @domain_ops: * * Table of interrupt domain operations for this IRQ chip. @@ -69,6 +76,11 @@ struct gpio_irq_chip { */ unsigned int *map; }; + +static inline struct gpio_irq_chip *to_gpio_irq_chip(struct irq_chip *chip) +{ + return container_of(chip, struct gpio_irq_chip, chip); +} #endif /** @@ -132,7 +144,6 @@ struct gpio_irq_chip { * safely. * @bgpio_dir: shadowed direction register for generic GPIO to clear/set * direction safely. - * @irqchip: GPIO IRQ chip impl, provided by GPIO driver * @irqdomain: Interrupt translation domain; responsible for mapping * between GPIO hwirq number and linux irq number * @irq_base: first linux IRQ number assigned to GPIO IRQ chip (deprecated) @@ -215,7 +226,6 @@ struct gpio_chip { * With CONFIG_GPIOLIB_IRQCHIP we get an irqchip inside the gpiolib * to handle IRQs for most practical cases. */ - struct irq_chip *irqchip; struct irq_domain *irqdomain; unsigned int irq_base; irq_flow_handler_t irq_handler; From patchwork Fri Sep 1 18:57:23 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Reding X-Patchwork-Id: 808975 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="C1Ee2/w2"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3xkTCL3qJsz9sQl for ; Sat, 2 Sep 2017 05:02:54 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752604AbdIATBd (ORCPT ); Fri, 1 Sep 2017 15:01:33 -0400 Received: from mail-wm0-f65.google.com ([74.125.82.65]:35764 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752367AbdIAS5p (ORCPT ); Fri, 1 Sep 2017 14:57:45 -0400 Received: by mail-wm0-f65.google.com with SMTP id e204so963573wma.2; Fri, 01 Sep 2017 11:57:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=DfPEhHEGNkd4RhSZqUa7rfcA6a5QDNVHpiIVlKirOCg=; b=C1Ee2/w2gIdzfJa7Wu8f+t9+hQzY/AqzJ+wxRE07Hx35rubAnm8+wiiKf+FYqdgPXp uHh9OIoT4ukBX8ewGWPwYUbumLejINWEAbXmuci2LXwDbne8ckSIkBCQXDU9kI76JbWk CeGhytStiIUDu+V6+NckaCmDTWt5jEGCmYuymRbbZnuKV906z17AU6RgxxCY6J69jDSQ dZSFyPQ+7sBh+Rv/LKCXY2w+eC3peRizjL649PSJh20dQ8/gRwH8z99Lp065ZDoZHnSI 70OuCLHoZ/ahDEAN/pKoswa2IR1db8O+f9Ft0rHdMVx4K35Keq3D0J8zgVhJUxgWN0c7 50Tw== 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=DfPEhHEGNkd4RhSZqUa7rfcA6a5QDNVHpiIVlKirOCg=; b=ehCICKo2DFwcjeDCcwf4LFTKyoWzIR+jV2FoZZ0XLZTMP1+RevbbklsFOH3aPgnCc2 1QeOKoA31yhArIqpLcTTyn0MPqIJvZj64kywA694fjF0BIOncAbYRZ/RKi9VsWm6yGNb OWcDOcMYhzGJeXFTUyN0XESD8AAhlPugkxOjsfkjIXdJIdtkbUH+w/wGsi9b1Ab2aLzn cjn9JXpsI+U4L/Ar0HYin/r5ukGoqQxFA4GCs31ZJufTAcuumljKfadxWAWB1i0K/PRH vZb9CozHEccjDuymTO0RrDwYI3ftCrI5cJbSebLlEj8Wlm3XO97UEBUrKIYiit1hmPn/ 9ccA== X-Gm-Message-State: AHPjjUjI/HgOEuRDQTbuVJh24xYwxPgPxrc9Fmk3uMHS1n9DIGjqfVo2 11YKYUP0KgKLAsax X-Google-Smtp-Source: ADKCNb6uwCmL/lWjuEM3pdpWA4r7k84Xo9Q05JYapbNV6Z5fMpYG7AMW7iEDD/UvHC5jDY8VrvpZYA== X-Received: by 10.28.20.18 with SMTP id 18mr946625wmu.7.1504292263417; Fri, 01 Sep 2017 11:57:43 -0700 (PDT) Received: from localhost (p200300E41BD6D60076D02BFFFE273F51.dip0.t-ipconnect.de. [2003:e4:1bd6:d600:76d0:2bff:fe27:3f51]) by smtp.gmail.com with ESMTPSA id u15sm1049846wrg.31.2017.09.01.11.57.42 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 01 Sep 2017 11:57:42 -0700 (PDT) From: Thierry Reding To: Linus Walleij Cc: Jonathan Hunter , linux-gpio@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 03/16] gpio: Move irqdomain into struct gpio_irq_chip Date: Fri, 1 Sep 2017 20:57:23 +0200 Message-Id: <20170901185736.28051-4-thierry.reding@gmail.com> X-Mailer: git-send-email 2.13.3 In-Reply-To: <20170901185736.28051-1-thierry.reding@gmail.com> References: <20170901185736.28051-1-thierry.reding@gmail.com> Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Thierry Reding In order to consolidate the multiple ways to associate an IRQ chip with a GPIO chip, move more fields into the new struct gpio_irq_chip. Signed-off-by: Thierry Reding --- Documentation/gpio/driver.txt | 2 +- drivers/bcma/driver_gpio.c | 2 +- drivers/gpio/gpio-104-dio-48e.c | 2 +- drivers/gpio/gpio-104-idi-48.c | 2 +- drivers/gpio/gpio-104-idio-16.c | 2 +- drivers/gpio/gpio-adnp.c | 2 +- drivers/gpio/gpio-altera.c | 4 ++-- drivers/gpio/gpio-aspeed.c | 2 +- drivers/gpio/gpio-ath79.c | 2 +- drivers/gpio/gpio-brcmstb.c | 2 +- drivers/gpio/gpio-crystalcove.c | 2 +- drivers/gpio/gpio-dln2.c | 2 +- drivers/gpio/gpio-ftgpio010.c | 2 +- drivers/gpio/gpio-ingenic.c | 2 +- drivers/gpio/gpio-intel-mid.c | 2 +- drivers/gpio/gpio-lynxpoint.c | 2 +- drivers/gpio/gpio-max732x.c | 2 +- drivers/gpio/gpio-merrifield.c | 2 +- drivers/gpio/gpio-omap.c | 2 +- drivers/gpio/gpio-pca953x.c | 2 +- drivers/gpio/gpio-pcf857x.c | 2 +- drivers/gpio/gpio-pci-idio-16.c | 2 +- drivers/gpio/gpio-pl061.c | 2 +- drivers/gpio/gpio-rcar.c | 2 +- drivers/gpio/gpio-reg.c | 4 ++-- drivers/gpio/gpio-stmpe.c | 2 +- drivers/gpio/gpio-tc3589x.c | 2 +- drivers/gpio/gpio-vf610.c | 2 +- drivers/gpio/gpio-wcove.c | 2 +- drivers/gpio/gpio-ws16c48.c | 2 +- drivers/gpio/gpio-xgene-sb.c | 2 +- drivers/gpio/gpio-xlp.c | 2 +- drivers/gpio/gpio-zx.c | 2 +- drivers/gpio/gpio-zynq.c | 2 +- drivers/gpio/gpiolib.c | 32 +++++++++++++++-------------- drivers/pinctrl/bcm/pinctrl-bcm2835.c | 4 ++-- drivers/pinctrl/bcm/pinctrl-iproc-gpio.c | 2 +- drivers/pinctrl/intel/pinctrl-baytrail.c | 2 +- drivers/pinctrl/intel/pinctrl-cherryview.c | 2 +- drivers/pinctrl/intel/pinctrl-intel.c | 2 +- drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 2 +- drivers/pinctrl/nomadik/pinctrl-nomadik.c | 4 ++-- drivers/pinctrl/pinctrl-amd.c | 2 +- drivers/pinctrl/pinctrl-at91.c | 2 +- drivers/pinctrl/pinctrl-coh901.c | 2 +- drivers/pinctrl/pinctrl-mcp23s08.c | 2 +- drivers/pinctrl/pinctrl-oxnas.c | 2 +- drivers/pinctrl/pinctrl-pic32.c | 2 +- drivers/pinctrl/pinctrl-pistachio.c | 2 +- drivers/pinctrl/pinctrl-st.c | 2 +- drivers/pinctrl/pinctrl-sx150x.c | 2 +- drivers/pinctrl/qcom/pinctrl-msm.c | 2 +- drivers/pinctrl/sirf/pinctrl-atlas7.c | 2 +- drivers/pinctrl/sirf/pinctrl-sirf.c | 2 +- drivers/pinctrl/spear/pinctrl-plgpio.c | 2 +- drivers/platform/x86/intel_int0002_vgpio.c | 2 +- include/linux/gpio/driver.h | 11 +++++++--- 57 files changed, 84 insertions(+), 77 deletions(-) diff --git a/Documentation/gpio/driver.txt b/Documentation/gpio/driver.txt index fc1d2f83564d..dcf6af1d9e56 100644 --- a/Documentation/gpio/driver.txt +++ b/Documentation/gpio/driver.txt @@ -254,7 +254,7 @@ GPIO irqchips usually fall in one of two categories: static irqreturn_t omap_gpio_irq_handler(int irq, void *gpiobank) unsigned long wa_lock_flags; raw_spin_lock_irqsave(&bank->wa_lock, wa_lock_flags); - generic_handle_irq(irq_find_mapping(bank->chip.irqdomain, bit)); + generic_handle_irq(irq_find_mapping(bank->chip.irq.domain, bit)); raw_spin_unlock_irqrestore(&bank->wa_lock, wa_lock_flags); * GENERIC CHAINED GPIO irqchips: these are the same as "CHAINED GPIO irqchips", diff --git a/drivers/bcma/driver_gpio.c b/drivers/bcma/driver_gpio.c index 982d5781d3ce..2c0ffb77d738 100644 --- a/drivers/bcma/driver_gpio.c +++ b/drivers/bcma/driver_gpio.c @@ -113,7 +113,7 @@ static irqreturn_t bcma_gpio_irq_handler(int irq, void *dev_id) return IRQ_NONE; for_each_set_bit(gpio, &irqs, gc->ngpio) - generic_handle_irq(irq_find_mapping(gc->irqdomain, gpio)); + generic_handle_irq(irq_find_mapping(gc->irq.domain, gpio)); bcma_chipco_gpio_polarity(cc, irqs, val & irqs); return IRQ_HANDLED; diff --git a/drivers/gpio/gpio-104-dio-48e.c b/drivers/gpio/gpio-104-dio-48e.c index 598e209efa2d..bab3b94c5cbc 100644 --- a/drivers/gpio/gpio-104-dio-48e.c +++ b/drivers/gpio/gpio-104-dio-48e.c @@ -326,7 +326,7 @@ static irqreturn_t dio48e_irq_handler(int irq, void *dev_id) unsigned long gpio; for_each_set_bit(gpio, &irq_mask, 2) - generic_handle_irq(irq_find_mapping(chip->irqdomain, + generic_handle_irq(irq_find_mapping(chip->irq.domain, 19 + gpio*24)); raw_spin_lock(&dio48egpio->lock); diff --git a/drivers/gpio/gpio-104-idi-48.c b/drivers/gpio/gpio-104-idi-48.c index 51f046e29ff7..add859d59766 100644 --- a/drivers/gpio/gpio-104-idi-48.c +++ b/drivers/gpio/gpio-104-idi-48.c @@ -209,7 +209,7 @@ static irqreturn_t idi_48_irq_handler(int irq, void *dev_id) for_each_set_bit(bit_num, &irq_mask, 8) { gpio = bit_num + boundary * 8; - generic_handle_irq(irq_find_mapping(chip->irqdomain, + generic_handle_irq(irq_find_mapping(chip->irq.domain, gpio)); } } diff --git a/drivers/gpio/gpio-104-idio-16.c b/drivers/gpio/gpio-104-idio-16.c index ec2ce34ff473..2f16638a0589 100644 --- a/drivers/gpio/gpio-104-idio-16.c +++ b/drivers/gpio/gpio-104-idio-16.c @@ -199,7 +199,7 @@ static irqreturn_t idio_16_irq_handler(int irq, void *dev_id) int gpio; for_each_set_bit(gpio, &idio16gpio->irq_mask, chip->ngpio) - generic_handle_irq(irq_find_mapping(chip->irqdomain, gpio)); + generic_handle_irq(irq_find_mapping(chip->irq.domain, gpio)); raw_spin_lock(&idio16gpio->lock); diff --git a/drivers/gpio/gpio-adnp.c b/drivers/gpio/gpio-adnp.c index 89863ea25de1..9d143ae4219f 100644 --- a/drivers/gpio/gpio-adnp.c +++ b/drivers/gpio/gpio-adnp.c @@ -323,7 +323,7 @@ static irqreturn_t adnp_irq(int irq, void *data) for_each_set_bit(bit, &pending, 8) { unsigned int child_irq; - child_irq = irq_find_mapping(adnp->gpio.irqdomain, + child_irq = irq_find_mapping(adnp->gpio.irq.domain, base + bit); handle_nested_irq(child_irq); } diff --git a/drivers/gpio/gpio-altera.c b/drivers/gpio/gpio-altera.c index ccc02ed65b3c..8e76d390e653 100644 --- a/drivers/gpio/gpio-altera.c +++ b/drivers/gpio/gpio-altera.c @@ -211,7 +211,7 @@ static void altera_gpio_irq_edge_handler(struct irq_desc *desc) altera_gc = gpiochip_get_data(irq_desc_get_handler_data(desc)); chip = irq_desc_get_chip(desc); mm_gc = &altera_gc->mmchip; - irqdomain = altera_gc->mmchip.gc.irqdomain; + irqdomain = altera_gc->mmchip.gc.irq.domain; chained_irq_enter(chip, desc); @@ -239,7 +239,7 @@ static void altera_gpio_irq_leveL_high_handler(struct irq_desc *desc) altera_gc = gpiochip_get_data(irq_desc_get_handler_data(desc)); chip = irq_desc_get_chip(desc); mm_gc = &altera_gc->mmchip; - irqdomain = altera_gc->mmchip.gc.irqdomain; + irqdomain = altera_gc->mmchip.gc.irq.domain; chained_irq_enter(chip, desc); diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c index bfc53995064a..a9342b471359 100644 --- a/drivers/gpio/gpio-aspeed.c +++ b/drivers/gpio/gpio-aspeed.c @@ -466,7 +466,7 @@ static void aspeed_gpio_irq_handler(struct irq_desc *desc) reg = ioread32(bank_irq_reg(data, bank, GPIO_IRQ_STATUS)); for_each_set_bit(p, ®, 32) { - girq = irq_find_mapping(gc->irqdomain, i * 32 + p); + girq = irq_find_mapping(gc->irq.domain, i * 32 + p); generic_handle_irq(girq); } diff --git a/drivers/gpio/gpio-ath79.c b/drivers/gpio/gpio-ath79.c index f33d4a5fe671..299e9f7b6b9d 100644 --- a/drivers/gpio/gpio-ath79.c +++ b/drivers/gpio/gpio-ath79.c @@ -208,7 +208,7 @@ static void ath79_gpio_irq_handler(struct irq_desc *desc) if (pending) { for_each_set_bit(irq, &pending, gc->ngpio) generic_handle_irq( - irq_linear_revmap(gc->irqdomain, irq)); + irq_linear_revmap(gc->irq.domain, irq)); } chained_irq_exit(irqchip, desc); diff --git a/drivers/gpio/gpio-brcmstb.c b/drivers/gpio/gpio-brcmstb.c index dd0308cc8bb0..4aadbae3c43f 100644 --- a/drivers/gpio/gpio-brcmstb.c +++ b/drivers/gpio/gpio-brcmstb.c @@ -202,7 +202,7 @@ static irqreturn_t brcmstb_gpio_wake_irq_handler(int irq, void *data) static void brcmstb_gpio_irq_bank_handler(struct brcmstb_gpio_bank *bank) { struct brcmstb_gpio_priv *priv = bank->parent_priv; - struct irq_domain *irq_domain = bank->gc.irqdomain; + struct irq_domain *irq_domain = bank->gc.irq.domain; void __iomem *reg_base = priv->reg_base; unsigned long status; unsigned long flags; diff --git a/drivers/gpio/gpio-crystalcove.c b/drivers/gpio/gpio-crystalcove.c index e60156ec0c18..b6f0f729656c 100644 --- a/drivers/gpio/gpio-crystalcove.c +++ b/drivers/gpio/gpio-crystalcove.c @@ -295,7 +295,7 @@ static irqreturn_t crystalcove_gpio_irq_handler(int irq, void *data) for (gpio = 0; gpio < CRYSTALCOVE_GPIO_NUM; gpio++) { if (pending & BIT(gpio)) { - virq = irq_find_mapping(cg->chip.irqdomain, gpio); + virq = irq_find_mapping(cg->chip.irq.domain, gpio); handle_nested_irq(virq); } } diff --git a/drivers/gpio/gpio-dln2.c b/drivers/gpio/gpio-dln2.c index aecb847166f5..1dada68b9a27 100644 --- a/drivers/gpio/gpio-dln2.c +++ b/drivers/gpio/gpio-dln2.c @@ -420,7 +420,7 @@ static void dln2_gpio_event(struct platform_device *pdev, u16 echo, return; } - irq = irq_find_mapping(dln2->gpio.irqdomain, pin); + irq = irq_find_mapping(dln2->gpio.irq.domain, pin); if (!irq) { dev_err(dln2->gpio.parent, "pin %d not mapped to IRQ\n", pin); return; diff --git a/drivers/gpio/gpio-ftgpio010.c b/drivers/gpio/gpio-ftgpio010.c index e9386f8b67f5..b7896bae83ca 100644 --- a/drivers/gpio/gpio-ftgpio010.c +++ b/drivers/gpio/gpio-ftgpio010.c @@ -149,7 +149,7 @@ static void ftgpio_gpio_irq_handler(struct irq_desc *desc) stat = readl(g->base + GPIO_INT_STAT); if (stat) for_each_set_bit(offset, &stat, gc->ngpio) - generic_handle_irq(irq_find_mapping(gc->irqdomain, + generic_handle_irq(irq_find_mapping(gc->irq.domain, offset)); chained_irq_exit(irqchip, desc); diff --git a/drivers/gpio/gpio-ingenic.c b/drivers/gpio/gpio-ingenic.c index 254780730b95..15fb2bc796a8 100644 --- a/drivers/gpio/gpio-ingenic.c +++ b/drivers/gpio/gpio-ingenic.c @@ -242,7 +242,7 @@ static void ingenic_gpio_irq_handler(struct irq_desc *desc) flag = gpio_ingenic_read_reg(jzgc, JZ4740_GPIO_FLAG); for_each_set_bit(i, &flag, 32) - generic_handle_irq(irq_linear_revmap(gc->irqdomain, i)); + generic_handle_irq(irq_linear_revmap(gc->irq.domain, i)); chained_irq_exit(irq_chip, desc); } diff --git a/drivers/gpio/gpio-intel-mid.c b/drivers/gpio/gpio-intel-mid.c index b76ecee82c3f..629575ea46a0 100644 --- a/drivers/gpio/gpio-intel-mid.c +++ b/drivers/gpio/gpio-intel-mid.c @@ -295,7 +295,7 @@ static void intel_mid_irq_handler(struct irq_desc *desc) mask = BIT(gpio); /* Clear before handling so we can't lose an edge */ writel(mask, gedr); - generic_handle_irq(irq_find_mapping(gc->irqdomain, + generic_handle_irq(irq_find_mapping(gc->irq.domain, base + gpio)); } } diff --git a/drivers/gpio/gpio-lynxpoint.c b/drivers/gpio/gpio-lynxpoint.c index fbd393b46ce0..1e557b10d73e 100644 --- a/drivers/gpio/gpio-lynxpoint.c +++ b/drivers/gpio/gpio-lynxpoint.c @@ -255,7 +255,7 @@ static void lp_gpio_irq_handler(struct irq_desc *desc) mask = BIT(pin); /* Clear before handling so we don't lose an edge */ outl(mask, reg); - irq = irq_find_mapping(lg->chip.irqdomain, base + pin); + irq = irq_find_mapping(lg->chip.irq.domain, base + pin); generic_handle_irq(irq); } } diff --git a/drivers/gpio/gpio-max732x.c b/drivers/gpio/gpio-max732x.c index 7f4d26ce5f23..c04fae1ba32a 100644 --- a/drivers/gpio/gpio-max732x.c +++ b/drivers/gpio/gpio-max732x.c @@ -486,7 +486,7 @@ static irqreturn_t max732x_irq_handler(int irq, void *devid) do { level = __ffs(pending); - handle_nested_irq(irq_find_mapping(chip->gpio_chip.irqdomain, + handle_nested_irq(irq_find_mapping(chip->gpio_chip.irq.domain, level)); pending &= ~(1 << level); diff --git a/drivers/gpio/gpio-merrifield.c b/drivers/gpio/gpio-merrifield.c index ec8560298805..dd67a31ac337 100644 --- a/drivers/gpio/gpio-merrifield.c +++ b/drivers/gpio/gpio-merrifield.c @@ -357,7 +357,7 @@ static void mrfld_irq_handler(struct irq_desc *desc) for_each_set_bit(gpio, &pending, 32) { unsigned int irq; - irq = irq_find_mapping(gc->irqdomain, base + gpio); + irq = irq_find_mapping(gc->irq.domain, base + gpio); generic_handle_irq(irq); } } diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index dbf869fb63ce..ce27d6a586bf 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -733,7 +733,7 @@ static irqreturn_t omap_gpio_irq_handler(int irq, void *gpiobank) raw_spin_lock_irqsave(&bank->wa_lock, wa_lock_flags); - generic_handle_irq(irq_find_mapping(bank->chip.irqdomain, + generic_handle_irq(irq_find_mapping(bank->chip.irq.domain, bit)); raw_spin_unlock_irqrestore(&bank->wa_lock, diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c index 1b9dbf691ae7..babb7bd2ba59 100644 --- a/drivers/gpio/gpio-pca953x.c +++ b/drivers/gpio/gpio-pca953x.c @@ -608,7 +608,7 @@ static irqreturn_t pca953x_irq_handler(int irq, void *devid) for (i = 0; i < NBANK(chip); i++) { while (pending[i]) { level = __ffs(pending[i]); - handle_nested_irq(irq_find_mapping(chip->gpio_chip.irqdomain, + handle_nested_irq(irq_find_mapping(chip->gpio_chip.irq.domain, level + (BANK_SZ * i))); pending[i] &= ~(1 << level); nhandled++; diff --git a/drivers/gpio/gpio-pcf857x.c b/drivers/gpio/gpio-pcf857x.c index a4fd78b9c0e4..38fbb420c6cd 100644 --- a/drivers/gpio/gpio-pcf857x.c +++ b/drivers/gpio/gpio-pcf857x.c @@ -196,7 +196,7 @@ static irqreturn_t pcf857x_irq(int irq, void *data) mutex_unlock(&gpio->lock); for_each_set_bit(i, &change, gpio->chip.ngpio) - handle_nested_irq(irq_find_mapping(gpio->chip.irqdomain, i)); + handle_nested_irq(irq_find_mapping(gpio->chip.irq.domain, i)); return IRQ_HANDLED; } diff --git a/drivers/gpio/gpio-pci-idio-16.c b/drivers/gpio/gpio-pci-idio-16.c index 7de4f6a2cb49..57d1b7fbf07b 100644 --- a/drivers/gpio/gpio-pci-idio-16.c +++ b/drivers/gpio/gpio-pci-idio-16.c @@ -240,7 +240,7 @@ static irqreturn_t idio_16_irq_handler(int irq, void *dev_id) return IRQ_NONE; for_each_set_bit(gpio, &idio16gpio->irq_mask, chip->ngpio) - generic_handle_irq(irq_find_mapping(chip->irqdomain, gpio)); + generic_handle_irq(irq_find_mapping(chip->irq.domain, gpio)); raw_spin_lock(&idio16gpio->lock); diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c index 3d3d6b6645a7..646a5a12dd7b 100644 --- a/drivers/gpio/gpio-pl061.c +++ b/drivers/gpio/gpio-pl061.c @@ -221,7 +221,7 @@ static void pl061_irq_handler(struct irq_desc *desc) pending = readb(pl061->base + GPIOMIS); if (pending) { for_each_set_bit(offset, &pending, PL061_GPIO_NR) - generic_handle_irq(irq_find_mapping(gc->irqdomain, + generic_handle_irq(irq_find_mapping(gc->irq.domain, offset)); } diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c index 1f0871553fd2..5bd1339d5a48 100644 --- a/drivers/gpio/gpio-rcar.c +++ b/drivers/gpio/gpio-rcar.c @@ -206,7 +206,7 @@ static irqreturn_t gpio_rcar_irq_handler(int irq, void *dev_id) gpio_rcar_read(p, INTMSK))) { offset = __ffs(pending); gpio_rcar_write(p, INTCLR, BIT(offset)); - generic_handle_irq(irq_find_mapping(p->gpio_chip.irqdomain, + generic_handle_irq(irq_find_mapping(p->gpio_chip.irq.domain, offset)); irqs_handled++; } diff --git a/drivers/gpio/gpio-reg.c b/drivers/gpio/gpio-reg.c index e85903eddc68..23e771dba4c1 100644 --- a/drivers/gpio/gpio-reg.c +++ b/drivers/gpio/gpio-reg.c @@ -103,8 +103,8 @@ static int gpio_reg_to_irq(struct gpio_chip *gc, unsigned offset) struct gpio_reg *r = to_gpio_reg(gc); int irq = r->irqs[offset]; - if (irq >= 0 && r->irqdomain) - irq = irq_find_mapping(r->irqdomain, irq); + if (irq >= 0 && r->irq.domain) + irq = irq_find_mapping(r->irq.domain, irq); return irq; } diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c index 16cbc5702865..5aee24fe0254 100644 --- a/drivers/gpio/gpio-stmpe.c +++ b/drivers/gpio/gpio-stmpe.c @@ -397,7 +397,7 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev) while (stat) { int bit = __ffs(stat); int line = bank * 8 + bit; - int child_irq = irq_find_mapping(stmpe_gpio->chip.irqdomain, + int child_irq = irq_find_mapping(stmpe_gpio->chip.irq.domain, line); handle_nested_irq(child_irq); diff --git a/drivers/gpio/gpio-tc3589x.c b/drivers/gpio/gpio-tc3589x.c index 433b45ef332e..91a8ef8e7f3f 100644 --- a/drivers/gpio/gpio-tc3589x.c +++ b/drivers/gpio/gpio-tc3589x.c @@ -268,7 +268,7 @@ static irqreturn_t tc3589x_gpio_irq(int irq, void *dev) while (stat) { int bit = __ffs(stat); int line = i * 8 + bit; - int irq = irq_find_mapping(tc3589x_gpio->chip.irqdomain, + int irq = irq_find_mapping(tc3589x_gpio->chip.irq.domain, line); handle_nested_irq(irq); diff --git a/drivers/gpio/gpio-vf610.c b/drivers/gpio/gpio-vf610.c index cbe9e06861de..4610cc2938ad 100644 --- a/drivers/gpio/gpio-vf610.c +++ b/drivers/gpio/gpio-vf610.c @@ -160,7 +160,7 @@ static void vf610_gpio_irq_handler(struct irq_desc *desc) for_each_set_bit(pin, &irq_isfr, VF610_GPIO_PER_PORT) { vf610_gpio_writel(BIT(pin), port->base + PORT_ISFR); - generic_handle_irq(irq_find_mapping(port->gc.irqdomain, pin)); + generic_handle_irq(irq_find_mapping(port->gc.irq.domain, pin)); } chained_irq_exit(chip, desc); diff --git a/drivers/gpio/gpio-wcove.c b/drivers/gpio/gpio-wcove.c index 85341eab795d..dde7c6aecbb5 100644 --- a/drivers/gpio/gpio-wcove.c +++ b/drivers/gpio/gpio-wcove.c @@ -350,7 +350,7 @@ static irqreturn_t wcove_gpio_irq_handler(int irq, void *data) offset = (gpio > GROUP0_NR_IRQS) ? 1 : 0; mask = (offset == 1) ? BIT(gpio - GROUP0_NR_IRQS) : BIT(gpio); - virq = irq_find_mapping(wg->chip.irqdomain, gpio); + virq = irq_find_mapping(wg->chip.irq.domain, gpio); handle_nested_irq(virq); regmap_update_bits(wg->regmap, IRQ_STATUS_BASE + offset, mask, mask); diff --git a/drivers/gpio/gpio-ws16c48.c b/drivers/gpio/gpio-ws16c48.c index 5037974ac063..746648244bf3 100644 --- a/drivers/gpio/gpio-ws16c48.c +++ b/drivers/gpio/gpio-ws16c48.c @@ -332,7 +332,7 @@ static irqreturn_t ws16c48_irq_handler(int irq, void *dev_id) int_id = inb(ws16c48gpio->base + 8 + port); for_each_set_bit(gpio, &int_id, 8) generic_handle_irq(irq_find_mapping( - chip->irqdomain, gpio + 8*port)); + chip->irq.domain, gpio + 8*port)); } int_pending = inb(ws16c48gpio->base + 6) & 0x7; diff --git a/drivers/gpio/gpio-xgene-sb.c b/drivers/gpio/gpio-xgene-sb.c index 033258634b8c..e761fd7c5728 100644 --- a/drivers/gpio/gpio-xgene-sb.c +++ b/drivers/gpio/gpio-xgene-sb.c @@ -296,7 +296,7 @@ static int xgene_gpio_sb_probe(struct platform_device *pdev) if (!priv->irq_domain) return -ENODEV; - priv->gc.irqdomain = priv->irq_domain; + priv->gc.irq.domain = priv->irq_domain; ret = devm_gpiochip_add_data(&pdev->dev, &priv->gc, priv); if (ret) { diff --git a/drivers/gpio/gpio-xlp.c b/drivers/gpio/gpio-xlp.c index d857e1d8e731..e74bd43a6974 100644 --- a/drivers/gpio/gpio-xlp.c +++ b/drivers/gpio/gpio-xlp.c @@ -225,7 +225,7 @@ static void xlp_gpio_generic_handler(struct irq_desc *desc) if (gpio_stat & BIT(gpio % XLP_GPIO_REGSZ)) generic_handle_irq(irq_find_mapping( - priv->chip.irqdomain, gpio)); + priv->chip.irq.domain, gpio)); } chained_irq_exit(irqchip, desc); } diff --git a/drivers/gpio/gpio-zx.c b/drivers/gpio/gpio-zx.c index be3a87da8438..5eacad9b2692 100644 --- a/drivers/gpio/gpio-zx.c +++ b/drivers/gpio/gpio-zx.c @@ -170,7 +170,7 @@ static void zx_irq_handler(struct irq_desc *desc) writew_relaxed(pending, chip->base + ZX_GPIO_IC); if (pending) { for_each_set_bit(offset, &pending, ZX_GPIO_NR) - generic_handle_irq(irq_find_mapping(gc->irqdomain, + generic_handle_irq(irq_find_mapping(gc->irq.domain, offset)); } diff --git a/drivers/gpio/gpio-zynq.c b/drivers/gpio/gpio-zynq.c index b3cc948a2d8b..75ee877e5cd5 100644 --- a/drivers/gpio/gpio-zynq.c +++ b/drivers/gpio/gpio-zynq.c @@ -562,7 +562,7 @@ static void zynq_gpio_handle_bank_irq(struct zynq_gpio *gpio, unsigned long pending) { unsigned int bank_offset = gpio->p_data->bank_min[bank_num]; - struct irq_domain *irqdomain = gpio->chip.irqdomain; + struct irq_domain *irqdomain = gpio->chip.irq.domain; int offset; if (!pending) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 4058adde7dc6..d8ea8a292978 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1560,7 +1560,7 @@ static void gpiochip_set_cascaded_irqchip(struct gpio_chip *gpiochip, { unsigned int offset; - if (!gpiochip->irqdomain) { + if (!gpiochip->irq.domain) { chip_err(gpiochip, "called %s before setting up irqchip\n", __func__); return; @@ -1587,7 +1587,7 @@ static void gpiochip_set_cascaded_irqchip(struct gpio_chip *gpiochip, for (offset = 0; offset < gpiochip->ngpio; offset++) { if (!gpiochip_irqchip_irq_valid(gpiochip, offset)) continue; - irq_set_parent(irq_find_mapping(gpiochip->irqdomain, offset), + irq_set_parent(irq_find_mapping(gpiochip->irq.domain, offset), parent_irq); } } @@ -1720,7 +1720,7 @@ static int gpiochip_to_irq(struct gpio_chip *chip, unsigned offset) { if (!gpiochip_irqchip_irq_valid(chip, offset)) return -ENXIO; - return irq_create_mapping(chip->irqdomain, offset); + return irq_create_mapping(chip->irq.domain, offset); } /** @@ -1780,10 +1780,10 @@ static int gpiochip_add_irqchip(struct gpio_chip *gpiochip) else ops = &gpiochip_domain_ops; - gpiochip->irqdomain = irq_domain_add_simple(np, gpiochip->ngpio, - gpiochip->irq_base, - ops, gpiochip); - if (!gpiochip->irqdomain) + gpiochip->irq.domain = irq_domain_add_simple(np, gpiochip->ngpio, + gpiochip->irq_base, + ops, gpiochip); + if (!gpiochip->irq.domain) return -EINVAL; /* @@ -1825,7 +1825,7 @@ static int gpiochip_add_irqchip(struct gpio_chip *gpiochip) if (!gpiochip_irqchip_irq_valid(gpiochip, i)) continue; - irq = irq_create_mapping(gpiochip->irqdomain, i); + irq = irq_create_mapping(gpiochip->irq.domain, i); if (!irq) { chip_err(gpiochip, "failed to create IRQ mapping for GPIO#%u\n", @@ -1849,7 +1849,7 @@ static int gpiochip_add_irqchip(struct gpio_chip *gpiochip) */ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip) { - unsigned int offset; + unsigned int offset, irq; acpi_gpiochip_free_interrupts(gpiochip); @@ -1869,14 +1869,16 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip) } /* Remove all IRQ mappings and delete the domain */ - if (gpiochip->irqdomain) { + if (gpiochip->irq.domain) { for (offset = 0; offset < gpiochip->ngpio; offset++) { if (!gpiochip_irqchip_irq_valid(gpiochip, offset)) continue; - irq_dispose_mapping( - irq_find_mapping(gpiochip->irqdomain, offset)); + + irq = irq_find_mapping(gpiochip->irq.domain, offset); + irq_dispose_mapping(irq); } - irq_domain_remove(gpiochip->irqdomain); + + irq_domain_remove(gpiochip->irq.domain); } if (gpiochip->irq.chip) { @@ -1962,10 +1964,10 @@ int gpiochip_irqchip_add_key(struct gpio_chip *gpiochip, gpiochip->irq_default_type = type; gpiochip->to_irq = gpiochip_to_irq; gpiochip->lock_key = lock_key; - gpiochip->irqdomain = irq_domain_add_simple(of_node, + gpiochip->irq.domain = irq_domain_add_simple(of_node, gpiochip->ngpio, first_irq, &gpiochip_domain_ops, gpiochip); - if (!gpiochip->irqdomain) { + if (!gpiochip->irq.domain) { gpiochip->irq.chip = NULL; return -EINVAL; } diff --git a/drivers/pinctrl/bcm/pinctrl-bcm2835.c b/drivers/pinctrl/bcm/pinctrl-bcm2835.c index 0944310225db..72d122748293 100644 --- a/drivers/pinctrl/bcm/pinctrl-bcm2835.c +++ b/drivers/pinctrl/bcm/pinctrl-bcm2835.c @@ -383,7 +383,7 @@ static void bcm2835_gpio_irq_handle_bank(struct bcm2835_pinctrl *pc, /* FIXME: no clue why the code looks up the type here */ type = pc->irq_type[gpio]; - generic_handle_irq(irq_linear_revmap(pc->gpio_chip.irqdomain, + generic_handle_irq(irq_linear_revmap(pc->gpio_chip.irq.domain, gpio)); } } @@ -665,7 +665,7 @@ static void bcm2835_pctl_pin_dbg_show(struct pinctrl_dev *pctldev, enum bcm2835_fsel fsel = bcm2835_pinctrl_fsel_get(pc, offset); const char *fname = bcm2835_functions[fsel]; int value = bcm2835_gpio_get_bit(pc, GPLEV0, offset); - int irq = irq_find_mapping(chip->irqdomain, offset); + int irq = irq_find_mapping(chip->irq.domain, offset); seq_printf(s, "function %s in %s; irq %d (%s)", fname, value ? "hi" : "lo", diff --git a/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c b/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c index 85a8c97d9dfe..b93f62dc8733 100644 --- a/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c +++ b/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c @@ -172,7 +172,7 @@ static void iproc_gpio_irq_handler(struct irq_desc *desc) for_each_set_bit(bit, &val, NGPIOS_PER_BANK) { unsigned pin = NGPIOS_PER_BANK * i + bit; - int child_irq = irq_find_mapping(gc->irqdomain, pin); + int child_irq = irq_find_mapping(gc->irq.domain, pin); /* * Clear the interrupt before invoking the diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index 0f3a02495aeb..5897981e5ed3 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -1627,7 +1627,7 @@ static void byt_gpio_irq_handler(struct irq_desc *desc) pending = readl(reg); raw_spin_unlock(&vg->lock); for_each_set_bit(pin, &pending, 32) { - virq = irq_find_mapping(vg->chip.irqdomain, base + pin); + virq = irq_find_mapping(vg->chip.irq.domain, base + pin); generic_handle_irq(virq); } } diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c index 04e929fd0ffe..1cd7043edbc1 100644 --- a/drivers/pinctrl/intel/pinctrl-cherryview.c +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c @@ -1523,7 +1523,7 @@ static void chv_gpio_irq_handler(struct irq_desc *desc) unsigned irq, offset; offset = pctrl->intr_lines[intr_line]; - irq = irq_find_mapping(gc->irqdomain, offset); + irq = irq_find_mapping(gc->irq.domain, offset); generic_handle_irq(irq); } diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index 8f8721538616..e4e167650f8a 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -1000,7 +1000,7 @@ static irqreturn_t intel_gpio_community_irq_handler(struct intel_pinctrl *pctrl, if (padno >= community->npins) break; - irq = irq_find_mapping(gc->irqdomain, + irq = irq_find_mapping(gc->irq.domain, community->pin_base + padno); generic_handle_irq(irq); diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c index b8b6ab072cd0..e66ff18ee362 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c @@ -592,7 +592,7 @@ static void armada_37xx_irq_handler(struct irq_desc *desc) struct gpio_chip *gc = irq_desc_get_handler_data(desc); struct irq_chip *chip = irq_desc_get_chip(desc); struct armada_37xx_pinctrl *info = gpiochip_get_data(gc); - struct irq_domain *d = gc->irqdomain; + struct irq_domain *d = gc->irq.domain; int i; chained_irq_enter(chip, desc); diff --git a/drivers/pinctrl/nomadik/pinctrl-nomadik.c b/drivers/pinctrl/nomadik/pinctrl-nomadik.c index a53f1a9b1ed2..f0e7a8c114b2 100644 --- a/drivers/pinctrl/nomadik/pinctrl-nomadik.c +++ b/drivers/pinctrl/nomadik/pinctrl-nomadik.c @@ -413,7 +413,7 @@ nmk_gpio_disable_lazy_irq(struct nmk_gpio_chip *nmk_chip, unsigned offset) u32 falling = nmk_chip->fimsc & BIT(offset); u32 rising = nmk_chip->rimsc & BIT(offset); int gpio = nmk_chip->chip.base + offset; - int irq = irq_find_mapping(nmk_chip->chip.irqdomain, offset); + int irq = irq_find_mapping(nmk_chip->chip.irq.domain, offset); struct irq_data *d = irq_get_irq_data(irq); if (!rising && !falling) @@ -815,7 +815,7 @@ static void __nmk_gpio_irq_handler(struct irq_desc *desc, u32 status) while (status) { int bit = __ffs(status); - generic_handle_irq(irq_find_mapping(chip->irqdomain, bit)); + generic_handle_irq(irq_find_mapping(chip->irq.domain, bit)); status &= ~BIT(bit); } diff --git a/drivers/pinctrl/pinctrl-amd.c b/drivers/pinctrl/pinctrl-amd.c index 38af1ec2df0c..11f05f1e33b3 100644 --- a/drivers/pinctrl/pinctrl-amd.c +++ b/drivers/pinctrl/pinctrl-amd.c @@ -531,7 +531,7 @@ static irqreturn_t amd_gpio_irq_handler(int irq, void *dev_id) regval = readl(regs + i); if (!(regval & PIN_IRQ_PENDING)) continue; - irq = irq_find_mapping(gc->irqdomain, irqnr + i); + irq = irq_find_mapping(gc->irq.domain, irqnr + i); generic_handle_irq(irq); /* Clear interrupt */ writel(regval, regs + i); diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index 569bc28cb909..03492e3c09fa 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -1603,7 +1603,7 @@ static void gpio_irq_handler(struct irq_desc *desc) for_each_set_bit(n, &isr, BITS_PER_LONG) { generic_handle_irq(irq_find_mapping( - gpio_chip->irqdomain, n)); + gpio_chip->irq.domain, n)); } } chained_irq_exit(chip, desc); diff --git a/drivers/pinctrl/pinctrl-coh901.c b/drivers/pinctrl/pinctrl-coh901.c index ac155e7d3412..7939b178c6ae 100644 --- a/drivers/pinctrl/pinctrl-coh901.c +++ b/drivers/pinctrl/pinctrl-coh901.c @@ -517,7 +517,7 @@ static void u300_gpio_irq_handler(struct irq_desc *desc) for_each_set_bit(irqoffset, &val, U300_GPIO_PINS_PER_PORT) { int offset = pinoffset + irqoffset; - int pin_irq = irq_find_mapping(chip->irqdomain, offset); + int pin_irq = irq_find_mapping(chip->irq.domain, offset); dev_dbg(gpio->dev, "GPIO IRQ %d on pin %d\n", pin_irq, offset); diff --git a/drivers/pinctrl/pinctrl-mcp23s08.c b/drivers/pinctrl/pinctrl-mcp23s08.c index 3e40d4245512..db19a2f2f575 100644 --- a/drivers/pinctrl/pinctrl-mcp23s08.c +++ b/drivers/pinctrl/pinctrl-mcp23s08.c @@ -537,7 +537,7 @@ static irqreturn_t mcp23s08_irq(int irq, void *data) ((gpio_bit_changed || intcap_changed) && (BIT(i) & mcp->irq_fall) && !gpio_set) || defval_changed) { - child_irq = irq_find_mapping(mcp->chip.irqdomain, i); + child_irq = irq_find_mapping(mcp->chip.irq.domain, i); handle_nested_irq(child_irq); } } diff --git a/drivers/pinctrl/pinctrl-oxnas.c b/drivers/pinctrl/pinctrl-oxnas.c index 494ec9a7573a..53ec22a51f5c 100644 --- a/drivers/pinctrl/pinctrl-oxnas.c +++ b/drivers/pinctrl/pinctrl-oxnas.c @@ -1064,7 +1064,7 @@ static void oxnas_gpio_irq_handler(struct irq_desc *desc) stat = readl(bank->reg_base + IRQ_PENDING); for_each_set_bit(pin, &stat, BITS_PER_LONG) - generic_handle_irq(irq_linear_revmap(gc->irqdomain, pin)); + generic_handle_irq(irq_linear_revmap(gc->irq.domain, pin)); chained_irq_exit(chip, desc); } diff --git a/drivers/pinctrl/pinctrl-pic32.c b/drivers/pinctrl/pinctrl-pic32.c index 31ceb958b3fe..96390228d388 100644 --- a/drivers/pinctrl/pinctrl-pic32.c +++ b/drivers/pinctrl/pinctrl-pic32.c @@ -2106,7 +2106,7 @@ static void pic32_gpio_irq_handler(struct irq_desc *desc) pending = pic32_gpio_get_pending(gc, stat); for_each_set_bit(pin, &pending, BITS_PER_LONG) - generic_handle_irq(irq_linear_revmap(gc->irqdomain, pin)); + generic_handle_irq(irq_linear_revmap(gc->irq.domain, pin)); chained_irq_exit(chip, desc); } diff --git a/drivers/pinctrl/pinctrl-pistachio.c b/drivers/pinctrl/pinctrl-pistachio.c index 55375b1b3cc8..302190d1558d 100644 --- a/drivers/pinctrl/pinctrl-pistachio.c +++ b/drivers/pinctrl/pinctrl-pistachio.c @@ -1307,7 +1307,7 @@ static void pistachio_gpio_irq_handler(struct irq_desc *desc) pending = gpio_readl(bank, GPIO_INTERRUPT_STATUS) & gpio_readl(bank, GPIO_INTERRUPT_EN); for_each_set_bit(pin, &pending, 16) - generic_handle_irq(irq_linear_revmap(gc->irqdomain, pin)); + generic_handle_irq(irq_linear_revmap(gc->irq.domain, pin)); chained_irq_exit(chip, desc); } diff --git a/drivers/pinctrl/pinctrl-st.c b/drivers/pinctrl/pinctrl-st.c index a5205b94b2e6..2081c67667a8 100644 --- a/drivers/pinctrl/pinctrl-st.c +++ b/drivers/pinctrl/pinctrl-st.c @@ -1408,7 +1408,7 @@ static void __gpio_irq_handler(struct st_gpio_bank *bank) continue; } - generic_handle_irq(irq_find_mapping(bank->gpio_chip.irqdomain, n)); + generic_handle_irq(irq_find_mapping(bank->gpio_chip.irq.domain, n)); } } } diff --git a/drivers/pinctrl/pinctrl-sx150x.c b/drivers/pinctrl/pinctrl-sx150x.c index 7450f5118445..7db4f6a6eb17 100644 --- a/drivers/pinctrl/pinctrl-sx150x.c +++ b/drivers/pinctrl/pinctrl-sx150x.c @@ -561,7 +561,7 @@ static irqreturn_t sx150x_irq_thread_fn(int irq, void *dev_id) status = val; for_each_set_bit(n, &status, pctl->data->ngpios) - handle_nested_irq(irq_find_mapping(pctl->gpio.irqdomain, n)); + handle_nested_irq(irq_find_mapping(pctl->gpio.irq.domain, n)); return IRQ_HANDLED; } diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c index ff491da64dab..7a960590ecaa 100644 --- a/drivers/pinctrl/qcom/pinctrl-msm.c +++ b/drivers/pinctrl/qcom/pinctrl-msm.c @@ -795,7 +795,7 @@ static void msm_gpio_irq_handler(struct irq_desc *desc) g = &pctrl->soc->groups[i]; val = readl(pctrl->regs + g->intr_status_reg); if (val & BIT(g->intr_status_bit)) { - irq_pin = irq_find_mapping(gc->irqdomain, i); + irq_pin = irq_find_mapping(gc->irq.domain, i); generic_handle_irq(irq_pin); handled++; } diff --git a/drivers/pinctrl/sirf/pinctrl-atlas7.c b/drivers/pinctrl/sirf/pinctrl-atlas7.c index 4db9323251e3..f5cef6e5fa3e 100644 --- a/drivers/pinctrl/sirf/pinctrl-atlas7.c +++ b/drivers/pinctrl/sirf/pinctrl-atlas7.c @@ -5820,7 +5820,7 @@ static void atlas7_gpio_handle_irq(struct irq_desc *desc) __func__, gc->label, bank->gpio_offset + pin_in_bank); generic_handle_irq( - irq_find_mapping(gc->irqdomain, + irq_find_mapping(gc->irq.domain, bank->gpio_offset + pin_in_bank)); } diff --git a/drivers/pinctrl/sirf/pinctrl-sirf.c b/drivers/pinctrl/sirf/pinctrl-sirf.c index d3ef05973901..8b14a1f1e671 100644 --- a/drivers/pinctrl/sirf/pinctrl-sirf.c +++ b/drivers/pinctrl/sirf/pinctrl-sirf.c @@ -587,7 +587,7 @@ static void sirfsoc_gpio_handle_irq(struct irq_desc *desc) if ((status & 0x1) && (ctrl & SIRFSOC_GPIO_CTL_INTR_EN_MASK)) { pr_debug("%s: gpio id %d idx %d happens\n", __func__, bank->id, idx); - generic_handle_irq(irq_find_mapping(gc->irqdomain, idx + + generic_handle_irq(irq_find_mapping(gc->irq.domain, idx + bank->id * SIRFSOC_GPIO_BANK_SIZE)); } diff --git a/drivers/pinctrl/spear/pinctrl-plgpio.c b/drivers/pinctrl/spear/pinctrl-plgpio.c index cf6d68c7345b..72ae6bccee55 100644 --- a/drivers/pinctrl/spear/pinctrl-plgpio.c +++ b/drivers/pinctrl/spear/pinctrl-plgpio.c @@ -401,7 +401,7 @@ static void plgpio_irq_handler(struct irq_desc *desc) /* get correct irq line number */ pin = i * MAX_GPIO_PER_REG + pin; generic_handle_irq( - irq_find_mapping(gc->irqdomain, pin)); + irq_find_mapping(gc->irq.domain, pin)); } } chained_irq_exit(irqchip, desc); diff --git a/drivers/platform/x86/intel_int0002_vgpio.c b/drivers/platform/x86/intel_int0002_vgpio.c index 92dc230ef5b2..f6b3af73dea5 100644 --- a/drivers/platform/x86/intel_int0002_vgpio.c +++ b/drivers/platform/x86/intel_int0002_vgpio.c @@ -119,7 +119,7 @@ static irqreturn_t int0002_irq(int irq, void *data) if (!(gpe_sts_reg & GPE0A_PME_B0_STS_BIT)) return IRQ_NONE; - generic_handle_irq(irq_find_mapping(chip->irqdomain, + generic_handle_irq(irq_find_mapping(chip->irq.domain, GPE0A_PME_B0_VIRT_GPIO_PIN)); pm_system_wakeup(); diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 974247646886..031037bb8670 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -32,6 +32,14 @@ struct gpio_irq_chip { struct irq_chip *chip; /** + * @domain: + * + * Interrupt translation domain; responsible for mapping between GPIO + * hwirq number and Linux IRQ number. + */ + struct irq_domain *domain; + + /** * @domain_ops: * * Table of interrupt domain operations for this IRQ chip. @@ -144,8 +152,6 @@ static inline struct gpio_irq_chip *to_gpio_irq_chip(struct irq_chip *chip) * safely. * @bgpio_dir: shadowed direction register for generic GPIO to clear/set * direction safely. - * @irqdomain: Interrupt translation domain; responsible for mapping - * between GPIO hwirq number and linux irq number * @irq_base: first linux IRQ number assigned to GPIO IRQ chip (deprecated) * @irq_handler: the irq handler to use (often a predefined irq core function) * for GPIO IRQs, provided by GPIO driver @@ -226,7 +232,6 @@ struct gpio_chip { * With CONFIG_GPIOLIB_IRQCHIP we get an irqchip inside the gpiolib * to handle IRQs for most practical cases. */ - struct irq_domain *irqdomain; unsigned int irq_base; irq_flow_handler_t irq_handler; unsigned int irq_default_type; From patchwork Fri Sep 1 18:57:24 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Reding X-Patchwork-Id: 808968 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="PKXkEI80"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3xkT980T8Yz9t16 for ; Sat, 2 Sep 2017 05:00:57 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752481AbdIAS5v (ORCPT ); Fri, 1 Sep 2017 14:57:51 -0400 Received: from mail-wm0-f65.google.com ([74.125.82.65]:35951 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752437AbdIAS5s (ORCPT ); Fri, 1 Sep 2017 14:57:48 -0400 Received: by mail-wm0-f65.google.com with SMTP id p17so957300wmd.3; Fri, 01 Sep 2017 11:57:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=h56Jd1dDpBcvBeA7zpFoAUMTBV/z2MRsxs1xX0Cxu8A=; b=PKXkEI80M/erJyoX2glO1hQ4Hc9F4qBZL2hN5LZ546wfefX80cSFGRvUYdQS49OByr 7jc65WKbmBmM6drBKVbj2jVD+wvYNm34j5wKSMWO4mEDD/eL1NlhW+Q9QkrKZ0ZPT1UD uS4XN9BPOngFcJVTWiZb16viFwfCZDGgHkpVcfhIbL3T13GOQaaX2u0EfFrAABjZWUsn gpbgEowYvcRfuNh8mQNrgHVSUJefvZF6pNybe8Ao4EQ4SnCe4uONX3yvM8VxVcFV/4UB Ob1FbnZG1lbjNCTPr7SRiYBFc/fI0Mi56bWAqAi+HTWBZcZC600gIkhFEWewxCIEVx94 6MRw== 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=h56Jd1dDpBcvBeA7zpFoAUMTBV/z2MRsxs1xX0Cxu8A=; b=lO9d+mcNhLhlBurHtfBi4l+1VqmRmfRHvJayLkTnPVLiDNGsWG+pJDTVUqfInZCE6a 2dARkmE6UY4hpBQnsspHv6QZ1GPA0af5l5UxpjPWOO4ZXO7UxDrEkhZjg69Vkiyue2Ai x841lPReZM7uSnK0ABZMjkO/ploGQ7NYnqcr4oKX1nKDrVdtWGmiwQFBNNPtS8LHiw4E Eg4sR0Q5xC2sZkQZU6OpdGk5VKCug2xDxDIIKuS5rjnZ1/h7FuHtgnRKkFDLHAqIE4IC /iut7k8WDyw/Q/gHeCAsOhZNyW+csApJwj1qF4HqjzjH5RyjWpRqaiSWM+VpOCEbeOBK 5R/g== X-Gm-Message-State: AHPjjUg537lW1EOi2/RJU0DAS8dKwPAIbjQ4kBGW29cmScVv7xxZ/3/w O/QE5IDXb7hzcw== X-Google-Smtp-Source: ADKCNb7KUruPwo9rDjI8MfvB7qxQq5nBS1kbjzO8UiyHwaHve3njlKsIv/HZPZp3EHRiDSGRQ2lu8w== X-Received: by 10.28.136.140 with SMTP id k134mr1144885wmd.97.1504292265173; Fri, 01 Sep 2017 11:57:45 -0700 (PDT) Received: from localhost (p200300E41BD6D60076D02BFFFE273F51.dip0.t-ipconnect.de. [2003:e4:1bd6:d600:76d0:2bff:fe27:3f51]) by smtp.gmail.com with ESMTPSA id 66sm386419wmn.17.2017.09.01.11.57.43 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 01 Sep 2017 11:57:44 -0700 (PDT) From: Thierry Reding To: Linus Walleij Cc: Jonathan Hunter , linux-gpio@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 04/16] gpio: Move irq_base to struct gpio_irq_chip Date: Fri, 1 Sep 2017 20:57:24 +0200 Message-Id: <20170901185736.28051-5-thierry.reding@gmail.com> X-Mailer: git-send-email 2.13.3 In-Reply-To: <20170901185736.28051-1-thierry.reding@gmail.com> References: <20170901185736.28051-1-thierry.reding@gmail.com> Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Thierry Reding In order to consolidate the multiple ways to associate an IRQ chip with a GPIO chip, move more fields into the new struct gpio_irq_chip. Signed-off-by: Thierry Reding --- drivers/gpio/gpiolib.c | 2 +- drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 2 +- include/linux/gpio/driver.h | 10 ++++++++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index d8ea8a292978..e5ad28978d5c 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1781,7 +1781,7 @@ static int gpiochip_add_irqchip(struct gpio_chip *gpiochip) ops = &gpiochip_domain_ops; gpiochip->irq.domain = irq_domain_add_simple(np, gpiochip->ngpio, - gpiochip->irq_base, + gpiochip->irq.first, ops, gpiochip); if (!gpiochip->irq.domain) return -EINVAL; diff --git a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c index e66ff18ee362..8df8a4998f48 100644 --- a/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c +++ b/drivers/pinctrl/mvebu/pinctrl-armada-37xx.c @@ -681,7 +681,7 @@ static int armada_37xx_irqchip_register(struct platform_device *pdev, * the chained irq with all of them. */ for (i = 0; i < nrirqs; i++) { - struct irq_data *d = irq_get_irq_data(gc->irq_base + i); + struct irq_data *d = irq_get_irq_data(gc->irq.first + i); /* * The mask field is a "precomputed bitmask for diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 031037bb8670..9389406df0b1 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -47,6 +47,14 @@ struct gpio_irq_chip { const struct irq_domain_ops *domain_ops; /** + * @first: + * + * If not dynamically assigned, the base (first) IRQ to allocate GPIO + * chip IRQs from (deprecated). + */ + unsigned int first; + + /** * @parent_handler: * * The interrupt handler for the GPIO chip's parent interrupts, may be @@ -152,7 +160,6 @@ static inline struct gpio_irq_chip *to_gpio_irq_chip(struct irq_chip *chip) * safely. * @bgpio_dir: shadowed direction register for generic GPIO to clear/set * direction safely. - * @irq_base: first linux IRQ number assigned to GPIO IRQ chip (deprecated) * @irq_handler: the irq handler to use (often a predefined irq core function) * for GPIO IRQs, provided by GPIO driver * @irq_default_type: default IRQ triggering type applied during GPIO driver @@ -232,7 +239,6 @@ struct gpio_chip { * With CONFIG_GPIOLIB_IRQCHIP we get an irqchip inside the gpiolib * to handle IRQs for most practical cases. */ - unsigned int irq_base; irq_flow_handler_t irq_handler; unsigned int irq_default_type; unsigned int irq_chained_parent; From patchwork Fri Sep 1 18:57:25 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Reding X-Patchwork-Id: 808972 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="eOO/vAW/"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3xkTBK26k9z9sRW for ; Sat, 2 Sep 2017 05:01:58 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752454AbdIAS5u (ORCPT ); Fri, 1 Sep 2017 14:57:50 -0400 Received: from mail-wm0-f65.google.com ([74.125.82.65]:37046 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752438AbdIAS5s (ORCPT ); Fri, 1 Sep 2017 14:57:48 -0400 Received: by mail-wm0-f65.google.com with SMTP id x189so953454wmg.4; Fri, 01 Sep 2017 11:57:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Wac7PTBZaHThj8QOdMgOZ9R3+5mVhE5YItgB28I81Os=; b=eOO/vAW/OXBrSXb7NrkgvRsMlR/HHloY1LIR9tWZ/I+E2nqEHGFeJIc+3ujt6ehoFp YFApJHYDNrbICENAO2T8FJ0JiekPBblfZPAAGV7MJOqXFCrGsirRxhYvDgjXa5aL0CAQ 7capVjhvpINJYFC8VnUG2GL+9e7MAu5K6kGDxw7GFk/O1ZBMwyNNz7nvxSk59RvLc9ex ml2vMzr0M0+B2XA1+P8hK77Ypbb7MPAW/+OYMale0O2KT6pHMSnMmzzLilIiIXug8EK/ m95sHpLuKLDcXLgEuZ1KSk4f8gAEBR58mIKaEfVwu9Q30946kZJfSIencNOgkS71Vz0c ldJw== 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=Wac7PTBZaHThj8QOdMgOZ9R3+5mVhE5YItgB28I81Os=; b=PC/Xjp46x/+o+he+/axKKwzuSxzPqmAYR2sQOmEADSSbRL7yScEzajRcucelnCTReF jgBit4N/23ESxCzRO90k9yhG8JL889g1y8Ii1E2+oruTBtBG5tfMQP0DxvClYeVzh/JU Ce5RwGd6khHnUekYgHY5gTMWChjoylV6YbWA13g+nb1v/sFxrBZOvY0sZyRkKcgNnjfp 0rgpTTLbN3pNIP4vbjT/IrAB11tAyhmCJdT7nT6dr+knwboAM8XgeqgdSzQpRByheAUl KxcodwqZy/rqvuw4FbI3Ee1lzw8M2aXsRvR7MdRfbwKQ2ajKyWM1jvPWrzqNkEbaPCc5 tBig== X-Gm-Message-State: AHPjjUgJS/vctBLj8qpSSWd/rgV5OkrR27a+BE6xoFdJu2XKSxCk7hJd RXV2FEu0cLNUqj/U X-Google-Smtp-Source: ADKCNb40zSDUur95XlowR97Bs3dbkPejP79u+UnwKKYi1ly3sMK8e3qigPWjpnfaGaosdRofeWn9rw== X-Received: by 10.28.210.8 with SMTP id j8mr977528wmg.164.1504292267009; Fri, 01 Sep 2017 11:57:47 -0700 (PDT) Received: from localhost (p200300E41BD6D60076D02BFFFE273F51.dip0.t-ipconnect.de. [2003:e4:1bd6:d600:76d0:2bff:fe27:3f51]) by smtp.gmail.com with ESMTPSA id t135sm498827wmt.30.2017.09.01.11.57.45 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 01 Sep 2017 11:57:45 -0700 (PDT) From: Thierry Reding To: Linus Walleij Cc: Jonathan Hunter , linux-gpio@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 05/16] gpio: Move irq_handler to struct gpio_irq_chip Date: Fri, 1 Sep 2017 20:57:25 +0200 Message-Id: <20170901185736.28051-6-thierry.reding@gmail.com> X-Mailer: git-send-email 2.13.3 In-Reply-To: <20170901185736.28051-1-thierry.reding@gmail.com> References: <20170901185736.28051-1-thierry.reding@gmail.com> Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Thierry Reding In order to consolidate the multiple ways to associate an IRQ chip with a GPIO chip, move more fields into the new struct gpio_irq_chip. Signed-off-by: Thierry Reding --- drivers/gpio/gpiolib.c | 4 ++-- include/linux/gpio/driver.h | 11 ++++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index e5ad28978d5c..75fa734cfa98 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1656,7 +1656,7 @@ int gpiochip_irq_map(struct irq_domain *d, unsigned int irq, * category than their parents, so it won't report false recursion. */ irq_set_lockdep_class(irq, chip->lock_key); - irq_set_chip_and_handler(irq, chip->irq.chip, chip->irq_handler); + irq_set_chip_and_handler(irq, chip->irq.chip, chip->irq.handler); /* Chips that use nested thread handlers have them marked */ if (chip->irq_nested) irq_set_nested_thread(irq, 1); @@ -1960,7 +1960,7 @@ int gpiochip_irqchip_add_key(struct gpio_chip *gpiochip, } gpiochip->irq.chip = irqchip; - gpiochip->irq_handler = handler; + gpiochip->irq.handler = handler; gpiochip->irq_default_type = type; gpiochip->to_irq = gpiochip_to_irq; gpiochip->lock_key = lock_key; diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 9389406df0b1..b1398ea0c32a 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -55,6 +55,14 @@ struct gpio_irq_chip { unsigned int first; /** + * @handler: + * + * The IRQ handler to use (often a predefined IRQ core function) for + * GPIO IRQs, provided by GPIO driver. + */ + irq_flow_handler_t handler; + + /** * @parent_handler: * * The interrupt handler for the GPIO chip's parent interrupts, may be @@ -160,8 +168,6 @@ static inline struct gpio_irq_chip *to_gpio_irq_chip(struct irq_chip *chip) * safely. * @bgpio_dir: shadowed direction register for generic GPIO to clear/set * direction safely. - * @irq_handler: the irq handler to use (often a predefined irq core function) - * for GPIO IRQs, provided by GPIO driver * @irq_default_type: default IRQ triggering type applied during GPIO driver * initialization, provided by GPIO driver * @irq_chained_parent: GPIO IRQ chip parent/bank linux irq number, @@ -239,7 +245,6 @@ struct gpio_chip { * With CONFIG_GPIOLIB_IRQCHIP we get an irqchip inside the gpiolib * to handle IRQs for most practical cases. */ - irq_flow_handler_t irq_handler; unsigned int irq_default_type; unsigned int irq_chained_parent; bool irq_nested; From patchwork Fri Sep 1 18:57:26 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Reding X-Patchwork-Id: 808970 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="LOBZISWP"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3xkT9c6B5hz9sPm for ; Sat, 2 Sep 2017 05:01:17 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752360AbdIATBB (ORCPT ); Fri, 1 Sep 2017 15:01:01 -0400 Received: from mail-wm0-f66.google.com ([74.125.82.66]:37055 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752366AbdIAS5u (ORCPT ); Fri, 1 Sep 2017 14:57:50 -0400 Received: by mail-wm0-f66.google.com with SMTP id x189so953537wmg.4; Fri, 01 Sep 2017 11:57:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=1wVlPjQrEkrdROjpqBO9eS9yvsFEwPP7QoCqagPwxnY=; b=LOBZISWPgizhxeiTjByRQ3cmjpPdkWJL+sJdA1Pk3y5fygXRaZ4zzNqJFH+cq+T4T+ MEUjnQpDicWcYV9Ik5li+qg54cbonvwRXlNGApRmQo4ulPgdQ4hWqkreYtQCFxYeBZ6W bM61a9sycifgc3jQdX+Von3lXviGunwXj/4UYIqghsCHWX5rUvWxUlYDg+ayE9wrzEus xbyZMqjl7619xxvVM4QooZMmwyd3dhjuKfp6F0T4Nj0VKnSlTSYNTP2ENOebcUlEF4aE QeV0OSkiFe9iXR6rbYONq0F5bA4aGWQYsOwo+ZyDfEuNjfHSSxV3cuKSGNmcNy5aBYyA miog== 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=1wVlPjQrEkrdROjpqBO9eS9yvsFEwPP7QoCqagPwxnY=; b=g9tUM4DeNYxFJWrwLnl6rsFa6UhJaizl1JBs6HrHk6KFumLmeytQtYFdOLsMtT4LKc MEpfkcO5gxS3MHek57OMmklI7lU22DS0GZjvbkRCGqIToZuv3F1xY2tiobQ43o8/LKpq LSLpDP059ss9lfbJaic25J8Vb3vCtJkoX+9DYOSfV8gki1A4EzVuK+5t6IKzkiz45Zv/ cFhXnagZj+RM8MAHn+7da1IghPkGQ8fpZiV58PaxCD8y7NfLhM3eM5bqnIauuwe1TI4q PuCEvcIeH1o92mb7YbUU42tyLNKzuyX/kvYFJxH7+Bvz4y6nNkInyFAozlQuhyq9hTaX 1Daw== X-Gm-Message-State: AHPjjUgdFewrTSYZDwZCybLoQ6DePLtxkCROvANvDiJNzAXvMoIPonuk pCGRw9UjQCSUaKyu X-Google-Smtp-Source: ADKCNb5CvFQFvh10OwhXD0wCB9VBUYOUmiCF8nSOxoZzvsfOW5Y874SWz6yROAxCgS6VWosVaxihrw== X-Received: by 10.28.175.14 with SMTP id y14mr1054240wme.42.1504292268758; Fri, 01 Sep 2017 11:57:48 -0700 (PDT) Received: from localhost (p200300E41BD6D60076D02BFFFE273F51.dip0.t-ipconnect.de. [2003:e4:1bd6:d600:76d0:2bff:fe27:3f51]) by smtp.gmail.com with ESMTPSA id g106sm1070013wrd.4.2017.09.01.11.57.47 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 01 Sep 2017 11:57:47 -0700 (PDT) From: Thierry Reding To: Linus Walleij Cc: Jonathan Hunter , linux-gpio@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 06/16] gpio: Move irq_default_type to struct gpio_irq_chip Date: Fri, 1 Sep 2017 20:57:26 +0200 Message-Id: <20170901185736.28051-7-thierry.reding@gmail.com> X-Mailer: git-send-email 2.13.3 In-Reply-To: <20170901185736.28051-1-thierry.reding@gmail.com> References: <20170901185736.28051-1-thierry.reding@gmail.com> Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Thierry Reding In order to consolidate the multiple ways to associate an IRQ chip with a GPIO chip, move more fields into the new struct gpio_irq_chip. Signed-off-by: Thierry Reding --- drivers/gpio/gpiolib.c | 10 +++++----- include/linux/gpio/driver.h | 11 ++++++++--- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 75fa734cfa98..774d6047116a 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1666,8 +1666,8 @@ int gpiochip_irq_map(struct irq_domain *d, unsigned int irq, * No set-up of the hardware will happen if IRQ_TYPE_NONE * is passed as default type. */ - if (chip->irq_default_type != IRQ_TYPE_NONE) - irq_set_irq_type(irq, chip->irq_default_type); + if (chip->irq.default_type != IRQ_TYPE_NONE) + irq_set_irq_type(irq, chip->irq.default_type); return 0; } @@ -1744,7 +1744,7 @@ static int gpiochip_add_irqchip(struct gpio_chip *gpiochip) return -EINVAL; } - type = gpiochip->irq_default_type; + type = gpiochip->irq.default_type; np = gpiochip->parent->of_node; #ifdef CONFIG_OF_GPIO @@ -1773,7 +1773,7 @@ static int gpiochip_add_irqchip(struct gpio_chip *gpiochip) } gpiochip->to_irq = gpiochip_to_irq; - gpiochip->irq_default_type = type; + gpiochip->irq.default_type = type; if (gpiochip->irq.domain_ops) ops = gpiochip->irq.domain_ops; @@ -1961,7 +1961,7 @@ int gpiochip_irqchip_add_key(struct gpio_chip *gpiochip, gpiochip->irq.chip = irqchip; gpiochip->irq.handler = handler; - gpiochip->irq_default_type = type; + gpiochip->irq.default_type = type; gpiochip->to_irq = gpiochip_to_irq; gpiochip->lock_key = lock_key; gpiochip->irq.domain = irq_domain_add_simple(of_node, diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index b1398ea0c32a..bcf93afddfa6 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -63,6 +63,14 @@ struct gpio_irq_chip { irq_flow_handler_t handler; /** + * @default_type: + * + * Default IRQ triggering type applied during GPIO driver + * initialization, provided by GPIO driver. + */ + unsigned int default_type; + + /** * @parent_handler: * * The interrupt handler for the GPIO chip's parent interrupts, may be @@ -168,8 +176,6 @@ static inline struct gpio_irq_chip *to_gpio_irq_chip(struct irq_chip *chip) * safely. * @bgpio_dir: shadowed direction register for generic GPIO to clear/set * direction safely. - * @irq_default_type: default IRQ triggering type applied during GPIO driver - * initialization, provided by GPIO driver * @irq_chained_parent: GPIO IRQ chip parent/bank linux irq number, * provided by GPIO driver for chained interrupt (not for nested * interrupts). @@ -245,7 +251,6 @@ struct gpio_chip { * With CONFIG_GPIOLIB_IRQCHIP we get an irqchip inside the gpiolib * to handle IRQs for most practical cases. */ - unsigned int irq_default_type; unsigned int irq_chained_parent; bool irq_nested; bool irq_need_valid_mask; From patchwork Fri Sep 1 18:57:27 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Reding X-Patchwork-Id: 808967 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="nDZzXUm3"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3xkT904n2Mz9sRW for ; Sat, 2 Sep 2017 05:00:52 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752590AbdIATAd (ORCPT ); Fri, 1 Sep 2017 15:00:33 -0400 Received: from mail-wr0-f196.google.com ([209.85.128.196]:38801 "EHLO mail-wr0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752485AbdIAS5w (ORCPT ); Fri, 1 Sep 2017 14:57:52 -0400 Received: by mail-wr0-f196.google.com with SMTP id j3so475830wrb.5; Fri, 01 Sep 2017 11:57:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=lG2Dm9F5yVIXwgLQuCKN2MDVMOVbu4nMgk53BtrqMBE=; b=nDZzXUm3EIRWHEAj+4vPrsdUHJrzisbKVf5yTRHfMcR0co6uzTt5WgL4sqv6Lp+oeM 7WhcYftD/N6h4yGK3gysjuo6uqT7Ws+ZB4gtyZYw491BSMm4F8PPrZvHaI97bTcj5zrf IzVoEoawHWkuXuoGmqauYtrYu57KO0hnwc0b4Yl5kqB/qIFSmh72OxUiZLioEjSmMIDs jIk8jUOdCuy8KeQ6XIHQbRjhPC9wD4LA4cejZtB5DSrjC67sCYjK6EtnZc12Yx9YaoUb LpuAIMJFPTAcwNoiLxbt/4NSm6oXqSdd08Ae4L/MCXHddmOVDcKUQcp9+8+4Izv/JU0V OGjQ== 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=lG2Dm9F5yVIXwgLQuCKN2MDVMOVbu4nMgk53BtrqMBE=; b=uArkVWtGoll710gF/NZQ7IaweR8tnkiWrTjcV0iuA2N3VJu18uhLseSBZeUv2EhQP1 ImZwzB+1bUQqQL+WhoAOt+lOFPqlJXRUrg/cC+ERbj+qNshfjnUEgZIdcf5HHNtWSXxl D/8l0MCNzowje5bHxyY1HsPsgy9O0db3EEDTsKSQ+P3YcUhE1gvF0ODJWcnwg/H0OVUh 01H7Vl4+FnhAfxA6thJTx+5VwWP1UZX9pyEkDuvzk3kPogdVN4hWVV6CBgI85h5rnCoN mNs0CFNPb1I8wKSQ4eQxa2ZCnyxYFtM9yMTJTZlJ4DZxBtnPQZKq01P67mGl1rK2FnOp 23eQ== X-Gm-Message-State: AHPjjUjwolmnnsKQodbLm2h/BtK2K5oQ31rFzlakyiCxcavDNXFKg+pO 2LU8Ql6J5UGQlg== X-Google-Smtp-Source: ADKCNb6VCy84xCW6WPDEssD0P8qsoIqzJ68+zJQsjp2t+fgfc+l4viWlAv0rxJ4nX3huBNa4StjmDQ== X-Received: by 10.223.186.4 with SMTP id o4mr1917722wrg.236.1504292270451; Fri, 01 Sep 2017 11:57:50 -0700 (PDT) Received: from localhost (p200300E41BD6D60076D02BFFFE273F51.dip0.t-ipconnect.de. [2003:e4:1bd6:d600:76d0:2bff:fe27:3f51]) by smtp.gmail.com with ESMTPSA id k195sm885803wmg.43.2017.09.01.11.57.49 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 01 Sep 2017 11:57:49 -0700 (PDT) From: Thierry Reding To: Linus Walleij Cc: Jonathan Hunter , linux-gpio@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 07/16] gpio: Move irq_chained_parent to struct gpio_irq_chip Date: Fri, 1 Sep 2017 20:57:27 +0200 Message-Id: <20170901185736.28051-8-thierry.reding@gmail.com> X-Mailer: git-send-email 2.13.3 In-Reply-To: <20170901185736.28051-1-thierry.reding@gmail.com> References: <20170901185736.28051-1-thierry.reding@gmail.com> Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Thierry Reding In order to consolidate the multiple ways to associate an IRQ chip with a GPIO chip, move more fields into the new struct gpio_irq_chip. Signed-off-by: Thierry Reding --- drivers/gpio/gpiolib.c | 8 ++------ include/linux/gpio/driver.h | 4 ---- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 774d6047116a..f09cc89929f0 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1580,7 +1580,8 @@ static void gpiochip_set_cascaded_irqchip(struct gpio_chip *gpiochip, irq_set_chained_handler_and_data(parent_irq, parent_handler, gpiochip); - gpiochip->irq_chained_parent = parent_irq; + gpiochip->irq.parents = &parent_irq; + gpiochip->irq.num_parents = 1; } /* Set the parent IRQ for all affected IRQs */ @@ -1853,11 +1854,6 @@ static void gpiochip_irqchip_remove(struct gpio_chip *gpiochip) acpi_gpiochip_free_interrupts(gpiochip); - if (gpiochip->irq_chained_parent) { - irq_set_chained_handler(gpiochip->irq_chained_parent, NULL); - irq_set_handler_data(gpiochip->irq_chained_parent, NULL); - } - if (gpiochip->irq.chip) { struct gpio_irq_chip *irq = &gpiochip->irq; unsigned int i; diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index bcf93afddfa6..c3eafd874884 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -176,9 +176,6 @@ static inline struct gpio_irq_chip *to_gpio_irq_chip(struct irq_chip *chip) * safely. * @bgpio_dir: shadowed direction register for generic GPIO to clear/set * direction safely. - * @irq_chained_parent: GPIO IRQ chip parent/bank linux irq number, - * provided by GPIO driver for chained interrupt (not for nested - * interrupts). * @irq_nested: True if set the interrupt handling is nested. * @irq_need_valid_mask: If set core allocates @irq_valid_mask with all * bits set to one @@ -251,7 +248,6 @@ struct gpio_chip { * With CONFIG_GPIOLIB_IRQCHIP we get an irqchip inside the gpiolib * to handle IRQs for most practical cases. */ - unsigned int irq_chained_parent; bool irq_nested; bool irq_need_valid_mask; unsigned long *irq_valid_mask; From patchwork Fri Sep 1 18:57:28 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Reding X-Patchwork-Id: 808965 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Pzwcx9pD"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3xkT8c32Hmz9sPt for ; Sat, 2 Sep 2017 05:00:32 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752519AbdIAS54 (ORCPT ); Fri, 1 Sep 2017 14:57:56 -0400 Received: from mail-wm0-f65.google.com ([74.125.82.65]:34279 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752516AbdIAS5x (ORCPT ); Fri, 1 Sep 2017 14:57:53 -0400 Received: by mail-wm0-f65.google.com with SMTP id l19so969453wmi.1; Fri, 01 Sep 2017 11:57:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=0jQSsIRyQ2mDinfnKtVeYyb7EEdXnkvYSys82YoLMHU=; b=Pzwcx9pDz2CGcIeiHVC9k32D0CEemC4SNSVgWa9xfhWgRdGUzvAKzBWv0471uKE9Ql klhV/2cv/V0gkOSTOLarpLLfrDJvYVYhqSHEG6zW6uaeeNiWcEJrjMITFGrMJtdTecxO QWlL7U7ajbNNWjZk2wzOzYI2mAbU0j2+kDhIbV246d22rkreCaGSpXbk1m4UsPuuuEhP Qv8s3bGhYSLJ+A+Jvh/0AuryFmfdFBLPcQkyl7k0bqm4Gxnfhv+z/G4WDKP5BZRmQU0v W41FZYgm8i+lslAfwHFS2etRQTjD6fmRJ48d5usUxwgnCae85TqSNIwm7Aa6wtVkijKd 9CIg== 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=0jQSsIRyQ2mDinfnKtVeYyb7EEdXnkvYSys82YoLMHU=; b=ekMaM4KVrsrPDfdslEMjy+kofzGUTrykm8Xe3pGur1tzJ7D08PD8isceup7p1KZ/ph PKnYLRs37ac4GU5dH9UwraDSQznOl1UNLMphZUfseGeeX2HU87X7ihgSuf479g+A/mI8 IQp0Kpiw8b/F9wRdmBCpjWGWoD94kb7DOYQVZYGQiDM2719VrCQv4NkmyTSh9cAJUkss b6u4/jRFwn1VC0zAIV8MfHWcnWtf6gN23ogoxvUl2viDoqxQu85Bnt2BSMIhNP16Dh84 9hunLrNv3g84nuF7xS/DQRuzc9YuOO0yUNxSFFcyw/fAEjBrU2Bah/+lZzS4xTTFmNlc C0uw== X-Gm-Message-State: AHPjjUgdnfb+PD4tO0CS2GlJJ12j9tNum4kQDI5bjXHNW1v/Gw9g8wUr AMOyJqaYgpddWA== X-Google-Smtp-Source: ADKCNb4NQTqv3P2Mpm0pFqxsYtSjeX7MabV3D9W5dII9Y91h/1OiTtlmyh1sppdqxgAZueS7oYotFw== X-Received: by 10.28.94.84 with SMTP id s81mr1020631wmb.3.1504292271937; Fri, 01 Sep 2017 11:57:51 -0700 (PDT) Received: from localhost (p200300E41BD6D60076D02BFFFE273F51.dip0.t-ipconnect.de. [2003:e4:1bd6:d600:76d0:2bff:fe27:3f51]) by smtp.gmail.com with ESMTPSA id p65sm927080wmg.44.2017.09.01.11.57.50 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 01 Sep 2017 11:57:51 -0700 (PDT) From: Thierry Reding To: Linus Walleij Cc: Jonathan Hunter , linux-gpio@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 08/16] gpio: Move irq_nested into struct gpio_irq_chip Date: Fri, 1 Sep 2017 20:57:28 +0200 Message-Id: <20170901185736.28051-9-thierry.reding@gmail.com> X-Mailer: git-send-email 2.13.3 In-Reply-To: <20170901185736.28051-1-thierry.reding@gmail.com> References: <20170901185736.28051-1-thierry.reding@gmail.com> Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Thierry Reding In order to consolidate the multiple ways to associate an IRQ chip with a GPIO chip, move more fields into the new struct gpio_irq_chip. Signed-off-by: Thierry Reding --- drivers/gpio/gpiolib.c | 12 ++++++------ include/linux/gpio/driver.h | 9 +++++++-- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index f09cc89929f0..f506473f5c70 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1624,7 +1624,7 @@ void gpiochip_set_nested_irqchip(struct gpio_chip *gpiochip, struct irq_chip *irqchip, unsigned int parent_irq) { - if (!gpiochip->irq_nested) { + if (!gpiochip->irq.nested) { chip_err(gpiochip, "tried to nest a chained gpiochip\n"); return; } @@ -1659,7 +1659,7 @@ int gpiochip_irq_map(struct irq_domain *d, unsigned int irq, irq_set_lockdep_class(irq, chip->lock_key); irq_set_chip_and_handler(irq, chip->irq.chip, chip->irq.handler); /* Chips that use nested thread handlers have them marked */ - if (chip->irq_nested) + if (chip->irq.nested) irq_set_nested_thread(irq, 1); irq_set_noprobe(irq); @@ -1678,7 +1678,7 @@ void gpiochip_irq_unmap(struct irq_domain *d, unsigned int irq) { struct gpio_chip *chip = d->host_data; - if (chip->irq_nested) + if (chip->irq.nested) irq_set_nested_thread(irq, 0); irq_set_chip_and_handler(irq, NULL, NULL); irq_set_chip_data(irq, NULL); @@ -1811,9 +1811,9 @@ static int gpiochip_add_irqchip(struct gpio_chip *gpiochip) data); } - gpiochip->irq_nested = false; + gpiochip->irq.nested = false; } else { - gpiochip->irq_nested = true; + gpiochip->irq.nested = true; } /* @@ -1930,7 +1930,7 @@ int gpiochip_irqchip_add_key(struct gpio_chip *gpiochip, pr_err("missing gpiochip .dev parent pointer\n"); return -EINVAL; } - gpiochip->irq_nested = nested; + gpiochip->irq.nested = nested; of_node = gpiochip->parent->of_node; #ifdef CONFIG_OF_GPIO /* diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index c3eafd874884..7d632a8932be 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -107,6 +107,13 @@ struct gpio_irq_chip { * A list of interrupt parents for each line of a GPIO chip. */ unsigned int *map; + + /** + * @nested: + * + * True if set the interrupt handling is nested. + */ + bool nested; }; static inline struct gpio_irq_chip *to_gpio_irq_chip(struct irq_chip *chip) @@ -176,7 +183,6 @@ static inline struct gpio_irq_chip *to_gpio_irq_chip(struct irq_chip *chip) * safely. * @bgpio_dir: shadowed direction register for generic GPIO to clear/set * direction safely. - * @irq_nested: True if set the interrupt handling is nested. * @irq_need_valid_mask: If set core allocates @irq_valid_mask with all * bits set to one * @irq_valid_mask: If not %NULL holds bitmask of GPIOs which are valid to @@ -248,7 +254,6 @@ struct gpio_chip { * With CONFIG_GPIOLIB_IRQCHIP we get an irqchip inside the gpiolib * to handle IRQs for most practical cases. */ - bool irq_nested; bool irq_need_valid_mask; unsigned long *irq_valid_mask; struct lock_class_key *lock_key; From patchwork Fri Sep 1 18:57:29 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Reding X-Patchwork-Id: 808964 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="ihbB8+g9"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3xkT8b0kNmz9sRV for ; Sat, 2 Sep 2017 05:00:31 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752537AbdIATAO (ORCPT ); Fri, 1 Sep 2017 15:00:14 -0400 Received: from mail-wm0-f67.google.com ([74.125.82.67]:35823 "EHLO mail-wm0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752437AbdIAS55 (ORCPT ); Fri, 1 Sep 2017 14:57:57 -0400 Received: by mail-wm0-f67.google.com with SMTP id e204so964017wma.2; Fri, 01 Sep 2017 11:57:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=IpEo3ef4V/rhZfDU7L+301FwxmTSGHikQkHtw7kInMo=; b=ihbB8+g9SCtRw6Scrht/rGG83KLfAW7zrYZEGULEBWjQzx0pFZ6e6Kt5ENRpgFpyYx A5LNXSYZQqJEaPUoQ7oUPY/k8Ewb4odNnnDb/q1QIuyAxBA5djul+y97fK1c7weYYFxZ q621QqPakozlDMKBhMn6xuYAoFvSkfPhOgpGEFnszfdcjfbGytXmI3ZMvODSTnYmkBa6 j4aYY8VcL94DEvfm1JVzia3ysBvPIz662eMKfbz364iVF+EZCOxbg8lgQE86AeJBXykx X9S7+Zd7ddaPhudAnzst5f0qdrK0xIdHk7AnzbSFt+5viO/CoEacm9s7/mCeC75gWYgZ PQqQ== 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=IpEo3ef4V/rhZfDU7L+301FwxmTSGHikQkHtw7kInMo=; b=ZPgsx1mMQJyrGJbYrRS06+Isbhk7xLzlXR55xSEue0292LlJbFPcIU5zzkfXIocNSs ZIXO4JiRBaj+fjOSpG+vMWp0uPWdge6cPbqk/ikJHahshMHcIPrPmWG2yIjCEhZAQjKj ODgJFdF82twT33aB/ILvNgIgPKoz/OVYzQvqUdkKp7Oxp5BlkJlRK38PNaCz9ehgZqWl 7eeWKggHujKnQ3a68PTWgGTP1qSc+SoeJ3wQm39qBfIQnND8JclBgF9o5DqYjIgELDR3 Sd2Z+9qsbR4bp7S7fUD48e/G4erPsWpZJkzGtK0nsIp6tDkOgutiBiFFZIQ/ItGayr+1 AVcA== X-Gm-Message-State: AHPjjUj6FxF0RfxwP4/n1aPXp/K3il9WqC13HaKWNwK2Mlw3jSIUqM1N x3EpWuUibHVENgjM X-Google-Smtp-Source: ADKCNb5xZ6QBK+DeoovM9Yrwc2ISjo9TKebuOI59C5L1OD9xcbzoDazhiizD7HO1UPm7M6JebLVjXA== X-Received: by 10.28.30.129 with SMTP id e123mr1025888wme.35.1504292275308; Fri, 01 Sep 2017 11:57:55 -0700 (PDT) Received: from localhost (p200300E41BD6D60076D02BFFFE273F51.dip0.t-ipconnect.de. [2003:e4:1bd6:d600:76d0:2bff:fe27:3f51]) by smtp.gmail.com with ESMTPSA id y2sm375579wmy.25.2017.09.01.11.57.52 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 01 Sep 2017 11:57:52 -0700 (PDT) From: Thierry Reding To: Linus Walleij Cc: Jonathan Hunter , linux-gpio@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 09/16] gpio: Move irq_valid_mask into struct gpio_irq_chip Date: Fri, 1 Sep 2017 20:57:29 +0200 Message-Id: <20170901185736.28051-10-thierry.reding@gmail.com> X-Mailer: git-send-email 2.13.3 In-Reply-To: <20170901185736.28051-1-thierry.reding@gmail.com> References: <20170901185736.28051-1-thierry.reding@gmail.com> Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Thierry Reding In order to consolidate the multiple ways to associate an IRQ chip with a GPIO chip, move more fields into the new struct gpio_irq_chip. Signed-off-by: Thierry Reding --- Documentation/gpio/driver.txt | 4 ++-- drivers/gpio/gpio-aspeed.c | 4 ++-- drivers/gpio/gpio-stmpe.c | 4 ++-- drivers/gpio/gpiolib.c | 16 ++++++++-------- drivers/pinctrl/intel/pinctrl-baytrail.c | 4 ++-- drivers/pinctrl/intel/pinctrl-cherryview.c | 4 ++-- drivers/platform/x86/intel_int0002_vgpio.c | 4 ++-- include/linux/gpio/driver.h | 21 +++++++++++++++------ 8 files changed, 35 insertions(+), 26 deletions(-) diff --git a/Documentation/gpio/driver.txt b/Documentation/gpio/driver.txt index dcf6af1d9e56..d8de1c7de85a 100644 --- a/Documentation/gpio/driver.txt +++ b/Documentation/gpio/driver.txt @@ -313,8 +313,8 @@ symbol: mark all the child IRQs as having the other IRQ as parent. If there is a need to exclude certain GPIOs from the IRQ domain, you can -set .irq_need_valid_mask of the gpiochip before gpiochip_add_data() is -called. This allocates an .irq_valid_mask with as many bits set as there +set .irq.need_valid_mask of the gpiochip before gpiochip_add_data() is +called. This allocates an .irq.valid_mask with as many bits set as there are GPIOs in the chip. Drivers can exclude GPIOs by clearing bits from this mask. The mask must be filled in before gpiochip_irqchip_add() or gpiochip_irqchip_add_nested() is called. diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c index a9342b471359..fbd551a0c634 100644 --- a/drivers/gpio/gpio-aspeed.c +++ b/drivers/gpio/gpio-aspeed.c @@ -498,7 +498,7 @@ static void set_irq_valid_mask(struct aspeed_gpio *gpio) if (i >= gpio->config->nr_gpios) break; - clear_bit(i, gpio->chip.irq_valid_mask); + clear_bit(i, gpio->chip.irq.valid_mask); } props++; @@ -853,7 +853,7 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev) gpio->chip.set_config = aspeed_gpio_set_config; gpio->chip.label = dev_name(&pdev->dev); gpio->chip.base = -1; - gpio->chip.irq_need_valid_mask = true; + gpio->chip.irq.need_valid_mask = true; rc = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio); if (rc < 0) diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c index 5aee24fe0254..5b99ff7e75ef 100644 --- a/drivers/gpio/gpio-stmpe.c +++ b/drivers/gpio/gpio-stmpe.c @@ -451,7 +451,7 @@ static int stmpe_gpio_probe(struct platform_device *pdev) of_property_read_u32(np, "st,norequest-mask", &stmpe_gpio->norequest_mask); if (stmpe_gpio->norequest_mask) - stmpe_gpio->chip.irq_need_valid_mask = true; + stmpe_gpio->chip.irq.need_valid_mask = true; if (irq < 0) dev_info(&pdev->dev, @@ -482,7 +482,7 @@ static int stmpe_gpio_probe(struct platform_device *pdev) /* Forbid unused lines to be mapped as IRQs */ for (i = 0; i < sizeof(u32); i++) if (stmpe_gpio->norequest_mask & BIT(i)) - clear_bit(i, stmpe_gpio->chip.irq_valid_mask); + clear_bit(i, stmpe_gpio->chip.irq.valid_mask); } ret = gpiochip_irqchip_add_nested(&stmpe_gpio->chip, &stmpe_gpio_irq_chip, diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index f506473f5c70..6cec36126f44 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1514,33 +1514,33 @@ static struct gpio_chip *find_chip_by_name(const char *name) static int gpiochip_irqchip_init_valid_mask(struct gpio_chip *gpiochip) { - if (!gpiochip->irq_need_valid_mask) + if (!gpiochip->irq.need_valid_mask) return 0; - gpiochip->irq_valid_mask = kcalloc(BITS_TO_LONGS(gpiochip->ngpio), + gpiochip->irq.valid_mask = kcalloc(BITS_TO_LONGS(gpiochip->ngpio), sizeof(long), GFP_KERNEL); - if (!gpiochip->irq_valid_mask) + if (!gpiochip->irq.valid_mask) return -ENOMEM; /* Assume by default all GPIOs are valid */ - bitmap_fill(gpiochip->irq_valid_mask, gpiochip->ngpio); + bitmap_fill(gpiochip->irq.valid_mask, gpiochip->ngpio); return 0; } static void gpiochip_irqchip_free_valid_mask(struct gpio_chip *gpiochip) { - kfree(gpiochip->irq_valid_mask); - gpiochip->irq_valid_mask = NULL; + kfree(gpiochip->irq.valid_mask); + gpiochip->irq.valid_mask = NULL; } static bool gpiochip_irqchip_irq_valid(const struct gpio_chip *gpiochip, unsigned int offset) { /* No mask means all valid */ - if (likely(!gpiochip->irq_valid_mask)) + if (likely(!gpiochip->irq.valid_mask)) return true; - return test_bit(offset, gpiochip->irq_valid_mask); + return test_bit(offset, gpiochip->irq.valid_mask); } /** diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c index 5897981e5ed3..9c1ca29c60b7 100644 --- a/drivers/pinctrl/intel/pinctrl-baytrail.c +++ b/drivers/pinctrl/intel/pinctrl-baytrail.c @@ -1660,7 +1660,7 @@ static void byt_gpio_irq_init_hw(struct byt_gpio *vg) value = readl(reg); if (value & BYT_DIRECT_IRQ_EN) { - clear_bit(i, gc->irq_valid_mask); + clear_bit(i, gc->irq.valid_mask); dev_dbg(dev, "excluding GPIO %d from IRQ domain\n", i); } else if ((value & BYT_PIN_MUX) == byt_get_gpio_mux(vg, i)) { byt_gpio_clear_triggering(vg, i); @@ -1703,7 +1703,7 @@ static int byt_gpio_probe(struct byt_gpio *vg) gc->can_sleep = false; gc->parent = &vg->pdev->dev; gc->ngpio = vg->soc_data->npins; - gc->irq_need_valid_mask = true; + gc->irq.need_valid_mask = true; #ifdef CONFIG_PM_SLEEP vg->saved_context = devm_kcalloc(&vg->pdev->dev, gc->ngpio, diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c index 1cd7043edbc1..e23def322de2 100644 --- a/drivers/pinctrl/intel/pinctrl-cherryview.c +++ b/drivers/pinctrl/intel/pinctrl-cherryview.c @@ -1584,7 +1584,7 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq) chip->label = dev_name(pctrl->dev); chip->parent = pctrl->dev; chip->base = -1; - chip->irq_need_valid_mask = need_valid_mask; + chip->irq.need_valid_mask = need_valid_mask; ret = devm_gpiochip_add_data(pctrl->dev, chip, pctrl); if (ret) { @@ -1616,7 +1616,7 @@ static int chv_gpio_probe(struct chv_pinctrl *pctrl, int irq) intsel >>= CHV_PADCTRL0_INTSEL_SHIFT; if (need_valid_mask && intsel >= pctrl->community->nirqs) - clear_bit(i, chip->irq_valid_mask); + clear_bit(i, chip->irq.valid_mask); } /* Clear all interrupts */ diff --git a/drivers/platform/x86/intel_int0002_vgpio.c b/drivers/platform/x86/intel_int0002_vgpio.c index f6b3af73dea5..f7b67e898abc 100644 --- a/drivers/platform/x86/intel_int0002_vgpio.c +++ b/drivers/platform/x86/intel_int0002_vgpio.c @@ -165,7 +165,7 @@ static int int0002_probe(struct platform_device *pdev) chip->direction_output = int0002_gpio_direction_output; chip->base = -1; chip->ngpio = GPE0A_PME_B0_VIRT_GPIO_PIN + 1; - chip->irq_need_valid_mask = true; + chip->irq.need_valid_mask = true; ret = devm_gpiochip_add_data(&pdev->dev, chip, NULL); if (ret) { @@ -173,7 +173,7 @@ static int int0002_probe(struct platform_device *pdev) return ret; } - bitmap_clear(chip->irq_valid_mask, 0, GPE0A_PME_B0_VIRT_GPIO_PIN); + bitmap_clear(chip->irq.valid_mask, 0, GPE0A_PME_B0_VIRT_GPIO_PIN); /* * We manually request the irq here instead of passing a flow-handler diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 7d632a8932be..f8d31e7da9cc 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -114,6 +114,21 @@ struct gpio_irq_chip { * True if set the interrupt handling is nested. */ bool nested; + + /** + * @need_valid_mask: + * + * If set core allocates @valid_mask with all bits set to one. + */ + bool need_valid_mask; + + /** + * @valid_mask: + * + * If not %NULL holds bitmask of GPIOs which are valid to be included + * in IRQ domain of the chip. + */ + unsigned long *valid_mask; }; static inline struct gpio_irq_chip *to_gpio_irq_chip(struct irq_chip *chip) @@ -183,10 +198,6 @@ static inline struct gpio_irq_chip *to_gpio_irq_chip(struct irq_chip *chip) * safely. * @bgpio_dir: shadowed direction register for generic GPIO to clear/set * direction safely. - * @irq_need_valid_mask: If set core allocates @irq_valid_mask with all - * bits set to one - * @irq_valid_mask: If not %NULL holds bitmask of GPIOs which are valid to - * be included in IRQ domain of the chip * @lock_key: per GPIO IRQ chip lockdep class * * A gpio_chip can help platforms abstract various sources of GPIOs so @@ -254,8 +265,6 @@ struct gpio_chip { * With CONFIG_GPIOLIB_IRQCHIP we get an irqchip inside the gpiolib * to handle IRQs for most practical cases. */ - bool irq_need_valid_mask; - unsigned long *irq_valid_mask; struct lock_class_key *lock_key; /** From patchwork Fri Sep 1 18:57:30 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Reding X-Patchwork-Id: 808961 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Lv1CGIXL"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3xkT8B1gNtz9sRV for ; Sat, 2 Sep 2017 05:00:10 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752600AbdIAS76 (ORCPT ); Fri, 1 Sep 2017 14:59:58 -0400 Received: from mail-wr0-f194.google.com ([209.85.128.194]:34193 "EHLO mail-wr0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752529AbdIAS56 (ORCPT ); Fri, 1 Sep 2017 14:57:58 -0400 Received: by mail-wr0-f194.google.com with SMTP id z91so491086wrc.1; Fri, 01 Sep 2017 11:57:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=25+pnbNESp32IKEPd1h621dfT9rkNInvAAy5fR9GZvI=; b=Lv1CGIXLNfbezDYeg1Lv1tTqMdUe392DP5Uh+DKK4bnw4kuDoL3FhCsZaXuN9d2BYC WTXrAib+Q4JuI1HvZWPXjdLwNMFkI5bYN9LrtOCYFJvn77SE9GVBDd6AsCsT4ZW6/H5l QuM4P2Vn6Y8hIYBpmg1Vqu8tUrU5VTMu1cHEpz23zawAQcruuvOnx+VeQxhiuJaZcYra e752qZrM/sxW2fdH3tP/zGKGeyIEZ36Wzr3hYZFCQZypJRHNH+9oa03doYT+0JKA8YsH 9/DGlC8xADwSal0sL1nXRcuuuRAmDd1QV83Sf0SM90uBGTNoYB0lkkVSUYQyyEFaZMO8 EYmQ== 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=25+pnbNESp32IKEPd1h621dfT9rkNInvAAy5fR9GZvI=; b=IKMCFmhYCDrZQ6z8WDyyf9GtFmpTorm+ANb0LRytVT2Gj1mSaaC02AylsMjltwkDB6 eaCEjePqCGHjtWpT00G8YdC0mUVaES+35rkza96eS9tfWTJB6y01JPrNWL9jySR5h74G 5kk3NjgQr2Fqm/oLwIarjBI9rZv7VJV00OgdV/rdQ51x7F65qq/8oDEfVeMUAOdz+GNQ 7tm2ePgmRl990VFH+r7LdFWr/gkrMBhs1PoIgGi6+5OOdbmt0eMruGZ/4qoVF8LYSvEw dXMUK5F+NUkOe0k5jyVOioAvVVhhWCOCEBeadRYIZosaLL7XcOU+s+/pVTrMxmP9GQPi WQKg== X-Gm-Message-State: AHPjjUgI9WdECQhONGGnNsw7OTunxiBeyeg7DfJKk3DUuF7E70i0SzoX YAe/CPlcK6XvZw== X-Google-Smtp-Source: ADKCNb5a2iVls4A5b/+WYRhRfaZyxB1DRhsXON/hyQKhdqwwklEBMdd7OtE8n+z3XaPTFKxdRHFFaA== X-Received: by 10.223.176.203 with SMTP id j11mr1986034wra.26.1504292276915; Fri, 01 Sep 2017 11:57:56 -0700 (PDT) Received: from localhost (p200300E41BD6D60076D02BFFFE273F51.dip0.t-ipconnect.de. [2003:e4:1bd6:d600:76d0:2bff:fe27:3f51]) by smtp.gmail.com with ESMTPSA id 6sm717925wre.0.2017.09.01.11.57.55 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 01 Sep 2017 11:57:56 -0700 (PDT) From: Thierry Reding To: Linus Walleij Cc: Jonathan Hunter , linux-gpio@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 10/16] gpio: Move lock_key into struct gpio_irq_chip Date: Fri, 1 Sep 2017 20:57:30 +0200 Message-Id: <20170901185736.28051-11-thierry.reding@gmail.com> X-Mailer: git-send-email 2.13.3 In-Reply-To: <20170901185736.28051-1-thierry.reding@gmail.com> References: <20170901185736.28051-1-thierry.reding@gmail.com> Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Thierry Reding In order to consolidate the multiple ways to associate an IRQ chip with a GPIO chip, move more fields into the new struct gpio_irq_chip. Signed-off-by: Thierry Reding --- drivers/gpio/gpiolib.c | 4 ++-- include/linux/gpio/driver.h | 9 +++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 6cec36126f44..7a16dd37bd3d 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1656,7 +1656,7 @@ int gpiochip_irq_map(struct irq_domain *d, unsigned int irq, * This lock class tells lockdep that GPIO irqs are in a different * category than their parents, so it won't report false recursion. */ - irq_set_lockdep_class(irq, chip->lock_key); + irq_set_lockdep_class(irq, chip->irq.lock_key); irq_set_chip_and_handler(irq, chip->irq.chip, chip->irq.handler); /* Chips that use nested thread handlers have them marked */ if (chip->irq.nested) @@ -1959,7 +1959,7 @@ int gpiochip_irqchip_add_key(struct gpio_chip *gpiochip, gpiochip->irq.handler = handler; gpiochip->irq.default_type = type; gpiochip->to_irq = gpiochip_to_irq; - gpiochip->lock_key = lock_key; + gpiochip->irq.lock_key = lock_key; gpiochip->irq.domain = irq_domain_add_simple(of_node, gpiochip->ngpio, first_irq, &gpiochip_domain_ops, gpiochip); diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index f8d31e7da9cc..c453e0716228 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -71,6 +71,13 @@ struct gpio_irq_chip { unsigned int default_type; /** + * @lock_key: + * + * Per GPIO IRQ chip lockdep class. + */ + struct lock_class_key *lock_key; + + /** * @parent_handler: * * The interrupt handler for the GPIO chip's parent interrupts, may be @@ -198,7 +205,6 @@ static inline struct gpio_irq_chip *to_gpio_irq_chip(struct irq_chip *chip) * safely. * @bgpio_dir: shadowed direction register for generic GPIO to clear/set * direction safely. - * @lock_key: per GPIO IRQ chip lockdep class * * A gpio_chip can help platforms abstract various sources of GPIOs so * they can all be accessed through a common programing interface. @@ -265,7 +271,6 @@ struct gpio_chip { * With CONFIG_GPIOLIB_IRQCHIP we get an irqchip inside the gpiolib * to handle IRQs for most practical cases. */ - struct lock_class_key *lock_key; /** * @irq: From patchwork Fri Sep 1 18:57:31 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Reding X-Patchwork-Id: 808957 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="L8FhFdya"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3xkT7W636qz9sPt for ; Sat, 2 Sep 2017 04:59:35 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752553AbdIAS6F (ORCPT ); Fri, 1 Sep 2017 14:58:05 -0400 Received: from mail-wm0-f68.google.com ([74.125.82.68]:36004 "EHLO mail-wm0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752516AbdIAS6A (ORCPT ); Fri, 1 Sep 2017 14:58:00 -0400 Received: by mail-wm0-f68.google.com with SMTP id p17so957740wmd.3; Fri, 01 Sep 2017 11:57:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=N6CWoRL6vHcnr8x34qF160gQMJP546jyL3aQNGVCJ8E=; b=L8FhFdyal8gT/nNb3FBHV4pKI0cuwsM+huQ3EPNGr4vTlkiZSILtcXjf9qBUtdY+RD 5gP0IY1oQF1OkN1Y/JQditDI+kWDmM48rnRgkLS8APPe1EGWQkvfxQ2+MbVYBt8LnbVR 1fcpiSCqrUCCgETYpm5O4agxG4GWUVXg0cqq7qybo4AaMGzEI3Yi6ztLYVT3+rOyJ5PA 9TVeCoGB31pJrazo+H1uVoH5YPbX/zyZWyeek0/7vFT7zIdFaqhsk049kfxG7wwthVjt 2bFdMdFL7+c2aLwyf4fruJMy8VfSLc0T9ykJcTEV6EuAqSS4pJLJ1xQ7vIC4FyuTGzUT g4qg== 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=N6CWoRL6vHcnr8x34qF160gQMJP546jyL3aQNGVCJ8E=; b=Ci9++yrO0YCj/fbaVQWCuTcKQC3bjxN7QixEC0NA8uqZxHzCF0D1LD7PNSGXeqrl8w 1ySsK6rfTmBAMIRl7TtxLQbuevW86lo62hn/r02OFRV3siPbQFB/Y4GYZ0XV9w7gyEJz xIq/Bd7uc7gdmDpearUvJECFYlRGxROLyuHDj5ai95wRwRovqKPNZcB9jFwRTm+6Jfsa uzlDBZP6/mvk7/KB/9nfsr7NjkaDvzP6soFahYY+WBRR6tTeOp05Dl/dcBDzkjj4/jhe IVNFCRPUV0zDvyg+6H3P5tmPj/aHgns78ERlGyapMXxazzjPkLtsM/3RYl8vw/u+0Ye0 Is4Q== X-Gm-Message-State: AHPjjUjM7le3QB3aG7BNkZ9AN+REZP4qdw2tP8mWBHSWmihF2p/sN8Kl 8C9mq2J2KpbaWw== X-Google-Smtp-Source: ADKCNb6kq/GPxjlOuYF2bV3jXBaEaPoA6yqUlcpxq+ZBipVFbPLDBtaS2yijcEmaiwYW5IeNbNqsdA== X-Received: by 10.28.129.79 with SMTP id c76mr955558wmd.179.1504292278685; Fri, 01 Sep 2017 11:57:58 -0700 (PDT) Received: from localhost (p200300E41BD6D60076D02BFFFE273F51.dip0.t-ipconnect.de. [2003:e4:1bd6:d600:76d0:2bff:fe27:3f51]) by smtp.gmail.com with ESMTPSA id b196sm718504wmd.29.2017.09.01.11.57.57 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 01 Sep 2017 11:57:57 -0700 (PDT) From: Thierry Reding To: Linus Walleij Cc: Jonathan Hunter , linux-gpio@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 11/16] gpio: Add Tegra186 support Date: Fri, 1 Sep 2017 20:57:31 +0200 Message-Id: <20170901185736.28051-12-thierry.reding@gmail.com> X-Mailer: git-send-email 2.13.3 In-Reply-To: <20170901185736.28051-1-thierry.reding@gmail.com> References: <20170901185736.28051-1-thierry.reding@gmail.com> Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Thierry Reding Tegra186 has two GPIO controllers that are largely register compatible between one another but are completely different from the controller found on earlier generations. Signed-off-by: Thierry Reding --- Changes in v4: - use platform_irq_count() instead of of_irq_count() Changes in v3: - make use of GPIOLIB_IRQCHIP for IRQ chip handling Changes in v2: - add pin names to allow easy lookup using the chardev interface - distinguish AON and main GPIO controllers by label - use gpiochip_get_data() instead of container_of() - use C99 initializers --- drivers/gpio/Kconfig | 9 + drivers/gpio/Makefile | 1 + drivers/gpio/gpio-tegra186.c | 624 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 634 insertions(+) create mode 100644 drivers/gpio/gpio-tegra186.c diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 3388d54ba114..f9e22c6fdd02 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -442,6 +442,15 @@ config GPIO_TEGRA help Say yes here to support GPIO pins on NVIDIA Tegra SoCs. +config GPIO_TEGRA186 + tristate "NVIDIA Tegra186 GPIO support" + default ARCH_TEGRA_186_SOC + depends on ARCH_TEGRA_186_SOC || COMPILE_TEST + depends on OF_GPIO + select GPIOLIB_IRQCHIP + help + Say yes here to support GPIO pins on NVIDIA Tegra186 SoCs. + config GPIO_TS4800 tristate "TS-4800 DIO blocks and compatibles" depends on OF_GPIO diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index aeb70e9de6f2..4cb7c9b93215 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -113,6 +113,7 @@ obj-$(CONFIG_GPIO_SYSCON) += gpio-syscon.o obj-$(CONFIG_GPIO_TB10X) += gpio-tb10x.o obj-$(CONFIG_GPIO_TC3589X) += gpio-tc3589x.o obj-$(CONFIG_GPIO_TEGRA) += gpio-tegra.o +obj-$(CONFIG_GPIO_TEGRA186) += gpio-tegra186.o obj-$(CONFIG_GPIO_THUNDERX) += gpio-thunderx.o obj-$(CONFIG_GPIO_TIMBERDALE) += gpio-timberdale.o obj-$(CONFIG_GPIO_PALMAS) += gpio-palmas.o diff --git a/drivers/gpio/gpio-tegra186.c b/drivers/gpio/gpio-tegra186.c new file mode 100644 index 000000000000..162dc6b41ae8 --- /dev/null +++ b/drivers/gpio/gpio-tegra186.c @@ -0,0 +1,624 @@ +/* + * Copyright (c) 2016-2017 NVIDIA Corporation + * + * Author: Thierry Reding + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#define TEGRA186_GPIO_ENABLE_CONFIG 0x00 +#define TEGRA186_GPIO_ENABLE_CONFIG_ENABLE BIT(0) +#define TEGRA186_GPIO_ENABLE_CONFIG_OUT BIT(1) +#define TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_TYPE_NONE (0x0 << 2) +#define TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_TYPE_LEVEL (0x1 << 2) +#define TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_TYPE_SINGLE_EDGE (0x2 << 2) +#define TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_TYPE_DOUBLE_EDGE (0x3 << 2) +#define TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_TYPE_MASK (0x3 << 2) +#define TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_LEVEL BIT(4) +#define TEGRA186_GPIO_ENABLE_CONFIG_INTERRUPT BIT(6) + +#define TEGRA186_GPIO_DEBOUNCE_CONTROL 0x04 +#define TEGRA186_GPIO_DEBOUNCE_CONTROL_THRESHOLD(x) ((x) & 0xff) + +#define TEGRA186_GPIO_INPUT 0x08 +#define TEGRA186_GPIO_INPUT_HIGH BIT(0) + +#define TEGRA186_GPIO_OUTPUT_CONTROL 0x0c +#define TEGRA186_GPIO_OUTPUT_CONTROL_FLOATED BIT(0) + +#define TEGRA186_GPIO_OUTPUT_VALUE 0x10 +#define TEGRA186_GPIO_OUTPUT_VALUE_HIGH BIT(0) + +#define TEGRA186_GPIO_INTERRUPT_CLEAR 0x14 + +#define TEGRA186_GPIO_INTERRUPT_STATUS(x) (0x100 + (x) * 4) + +struct tegra_gpio_port { + const char *name; + unsigned int offset; + unsigned int pins; + unsigned int irq; +}; + +struct tegra_gpio_soc { + const struct tegra_gpio_port *ports; + unsigned int num_ports; + const char *name; +}; + +struct tegra_gpio { + struct gpio_chip gpio; + struct irq_chip intc; + unsigned int num_irq; + unsigned int *irq; + + const struct tegra_gpio_soc *soc; + + void __iomem *base; +}; + +static const struct tegra_gpio_port * +tegra186_gpio_get_port(struct tegra_gpio *gpio, unsigned int *pin) +{ + unsigned int start = 0, i; + + for (i = 0; i < gpio->soc->num_ports; i++) { + const struct tegra_gpio_port *port = &gpio->soc->ports[i]; + + if (*pin >= start && *pin < start + port->pins) { + *pin -= start; + return port; + } + + start += port->pins; + } + + return NULL; +} + +static void __iomem *tegra186_gpio_get_base(struct tegra_gpio *gpio, + unsigned int pin) +{ + const struct tegra_gpio_port *port; + + port = tegra186_gpio_get_port(gpio, &pin); + if (!port) + return NULL; + + return gpio->base + port->offset + pin * 0x20; +} + +static int tegra186_gpio_get_direction(struct gpio_chip *chip, + unsigned int offset) +{ + struct tegra_gpio *gpio = gpiochip_get_data(chip); + void __iomem *base; + u32 value; + + base = tegra186_gpio_get_base(gpio, offset); + if (WARN_ON(base == NULL)) + return -ENODEV; + + value = readl(base + TEGRA186_GPIO_ENABLE_CONFIG); + if (value & TEGRA186_GPIO_ENABLE_CONFIG_OUT) + return 0; + + return 1; +} + +static int tegra186_gpio_direction_input(struct gpio_chip *chip, + unsigned int offset) +{ + struct tegra_gpio *gpio = gpiochip_get_data(chip); + void __iomem *base; + u32 value; + + base = tegra186_gpio_get_base(gpio, offset); + if (WARN_ON(base == NULL)) + return -ENODEV; + + value = readl(base + TEGRA186_GPIO_OUTPUT_CONTROL); + value |= TEGRA186_GPIO_OUTPUT_CONTROL_FLOATED; + writel(value, base + TEGRA186_GPIO_OUTPUT_CONTROL); + + value = readl(base + TEGRA186_GPIO_ENABLE_CONFIG); + value |= TEGRA186_GPIO_ENABLE_CONFIG_ENABLE; + value &= ~TEGRA186_GPIO_ENABLE_CONFIG_OUT; + writel(value, base + TEGRA186_GPIO_ENABLE_CONFIG); + + return 0; +} + +static int tegra186_gpio_direction_output(struct gpio_chip *chip, + unsigned int offset, int level) +{ + struct tegra_gpio *gpio = gpiochip_get_data(chip); + void __iomem *base; + u32 value; + + /* configure output level first */ + chip->set(chip, offset, level); + + base = tegra186_gpio_get_base(gpio, offset); + if (WARN_ON(base == NULL)) + return -EINVAL; + + /* set the direction */ + value = readl(base + TEGRA186_GPIO_OUTPUT_CONTROL); + value &= ~TEGRA186_GPIO_OUTPUT_CONTROL_FLOATED; + writel(value, base + TEGRA186_GPIO_OUTPUT_CONTROL); + + value = readl(base + TEGRA186_GPIO_ENABLE_CONFIG); + value |= TEGRA186_GPIO_ENABLE_CONFIG_ENABLE; + value |= TEGRA186_GPIO_ENABLE_CONFIG_OUT; + writel(value, base + TEGRA186_GPIO_ENABLE_CONFIG); + + return 0; +} + +static int tegra186_gpio_get(struct gpio_chip *chip, unsigned int offset) +{ + struct tegra_gpio *gpio = gpiochip_get_data(chip); + void __iomem *base; + u32 value; + + base = tegra186_gpio_get_base(gpio, offset); + if (WARN_ON(base == NULL)) + return -ENODEV; + + value = readl(base + TEGRA186_GPIO_ENABLE_CONFIG); + if (value & TEGRA186_GPIO_ENABLE_CONFIG_OUT) + value = readl(base + TEGRA186_GPIO_OUTPUT_VALUE); + else + value = readl(base + TEGRA186_GPIO_INPUT); + + return value & BIT(0); +} + +static void tegra186_gpio_set(struct gpio_chip *chip, unsigned int offset, + int level) +{ + struct tegra_gpio *gpio = gpiochip_get_data(chip); + void __iomem *base; + u32 value; + + base = tegra186_gpio_get_base(gpio, offset); + if (WARN_ON(base == NULL)) + return; + + value = readl(base + TEGRA186_GPIO_OUTPUT_VALUE); + if (level == 0) + value &= ~TEGRA186_GPIO_OUTPUT_VALUE_HIGH; + else + value |= TEGRA186_GPIO_OUTPUT_VALUE_HIGH; + + writel(value, base + TEGRA186_GPIO_OUTPUT_VALUE); +} + +static int tegra186_gpio_of_xlate(struct gpio_chip *chip, + const struct of_phandle_args *spec, + u32 *flags) +{ + struct tegra_gpio *gpio = gpiochip_get_data(chip); + unsigned int port, pin, i, offset = 0; + + if (WARN_ON(chip->of_gpio_n_cells < 2)) + return -EINVAL; + + if (WARN_ON(spec->args_count < chip->of_gpio_n_cells)) + return -EINVAL; + + port = spec->args[0] / 8; + pin = spec->args[0] % 8; + + if (port >= gpio->soc->num_ports) { + dev_err(chip->parent, "invalid port number: %u\n", port); + return -EINVAL; + } + + for (i = 0; i < port; i++) + offset += gpio->soc->ports[i].pins; + + if (flags) + *flags = spec->args[1]; + + return offset + pin; +} + +static void tegra186_irq_ack(struct irq_data *data) +{ + struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data); + void __iomem *base; + + base = tegra186_gpio_get_base(gpio, data->hwirq); + if (WARN_ON(base == NULL)) + return; + + writel(1, base + TEGRA186_GPIO_INTERRUPT_CLEAR); +} + +static void tegra186_irq_mask(struct irq_data *data) +{ + struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data); + void __iomem *base; + u32 value; + + base = tegra186_gpio_get_base(gpio, data->hwirq); + if (WARN_ON(base == NULL)) + return; + + value = readl(base + TEGRA186_GPIO_ENABLE_CONFIG); + value &= ~TEGRA186_GPIO_ENABLE_CONFIG_INTERRUPT; + writel(value, base + TEGRA186_GPIO_ENABLE_CONFIG); +} + +static void tegra186_irq_unmask(struct irq_data *data) +{ + struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data); + void __iomem *base; + u32 value; + + base = tegra186_gpio_get_base(gpio, data->hwirq); + if (WARN_ON(base == NULL)) + return; + + value = readl(base + TEGRA186_GPIO_ENABLE_CONFIG); + value |= TEGRA186_GPIO_ENABLE_CONFIG_INTERRUPT; + writel(value, base + TEGRA186_GPIO_ENABLE_CONFIG); +} + +static int tegra186_irq_set_type(struct irq_data *data, unsigned int flow) +{ + struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data); + void __iomem *base; + u32 value; + + base = tegra186_gpio_get_base(gpio, data->hwirq); + if (WARN_ON(base == NULL)) + return -ENODEV; + + value = readl(base + TEGRA186_GPIO_ENABLE_CONFIG); + value &= ~TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_TYPE_MASK; + value &= ~TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_LEVEL; + + switch (flow & IRQ_TYPE_SENSE_MASK) { + case IRQ_TYPE_NONE: + break; + + case IRQ_TYPE_EDGE_RISING: + value |= TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_TYPE_SINGLE_EDGE; + value |= TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_LEVEL; + break; + + case IRQ_TYPE_EDGE_FALLING: + value |= TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_TYPE_SINGLE_EDGE; + break; + + case IRQ_TYPE_EDGE_BOTH: + value |= TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_TYPE_DOUBLE_EDGE; + break; + + case IRQ_TYPE_LEVEL_HIGH: + value |= TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_TYPE_LEVEL; + value |= TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_LEVEL; + break; + + case IRQ_TYPE_LEVEL_LOW: + value |= TEGRA186_GPIO_ENABLE_CONFIG_TRIGGER_TYPE_LEVEL; + break; + + default: + return -EINVAL; + } + + writel(value, base + TEGRA186_GPIO_ENABLE_CONFIG); + + if ((flow & IRQ_TYPE_EDGE_BOTH) == 0) + irq_set_handler_locked(data, handle_level_irq); + else + irq_set_handler_locked(data, handle_edge_irq); + + return 0; +} + +static void tegra186_gpio_irq(struct irq_desc *desc) +{ + struct tegra_gpio *gpio = irq_desc_get_handler_data(desc); + struct irq_domain *domain = gpio->gpio.irq.domain; + struct irq_chip *chip = irq_desc_get_chip(desc); + unsigned int parent = irq_desc_get_irq(desc); + unsigned int i, offset = 0; + + chained_irq_enter(chip, desc); + + for (i = 0; i < gpio->soc->num_ports; i++) { + const struct tegra_gpio_port *port = &gpio->soc->ports[i]; + void __iomem *base = gpio->base + port->offset; + unsigned int pin, irq; + unsigned long value; + + /* skip ports that are not associated with this controller */ + if (parent != gpio->irq[port->irq]) + goto skip; + + value = readl(base + TEGRA186_GPIO_INTERRUPT_STATUS(1)); + + for_each_set_bit(pin, &value, port->pins) { + irq = irq_find_mapping(domain, offset + pin); + if (WARN_ON(irq == 0)) + continue; + + generic_handle_irq(irq); + } + +skip: + offset += port->pins; + } + + chained_irq_exit(chip, desc); +} + +static int tegra186_gpio_irq_domain_xlate(struct irq_domain *domain, + struct device_node *np, + const u32 *spec, unsigned int size, + unsigned long *hwirq, + unsigned int *type) +{ + struct tegra_gpio *gpio = gpiochip_get_data(domain->host_data); + unsigned int port, pin, i, offset = 0; + + if (size < 2) + return -EINVAL; + + port = spec[0] / 8; + pin = spec[0] % 8; + + if (port >= gpio->soc->num_ports) { + dev_err(gpio->gpio.parent, "invalid port number: %u\n", port); + return -EINVAL; + } + + for (i = 0; i < port; i++) + offset += gpio->soc->ports[i].pins; + + *type = spec[1] & IRQ_TYPE_SENSE_MASK; + *hwirq = offset + pin; + + return 0; +} + +static const struct irq_domain_ops tegra186_gpio_irq_domain_ops = { + .map = gpiochip_irq_map, + .unmap = gpiochip_irq_unmap, + .xlate = tegra186_gpio_irq_domain_xlate, +}; + +static struct lock_class_key tegra186_gpio_lock_class; + +static int tegra186_gpio_probe(struct platform_device *pdev) +{ + unsigned int i, j, offset; + struct gpio_irq_chip *irq; + struct tegra_gpio *gpio; + struct resource *res; + char **names; + int err; + + gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); + if (!gpio) + return -ENOMEM; + + gpio->soc = of_device_get_match_data(&pdev->dev); + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gpio"); + gpio->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(gpio->base)) + return PTR_ERR(gpio->base); + + err = platform_irq_count(pdev); + if (err < 0) + return err; + + gpio->num_irq = err; + + gpio->irq = devm_kcalloc(&pdev->dev, gpio->num_irq, sizeof(*gpio->irq), + GFP_KERNEL); + if (!gpio->irq) + return -ENOMEM; + + for (i = 0; i < gpio->num_irq; i++) { + err = platform_get_irq(pdev, i); + if (err < 0) + return err; + + gpio->irq[i] = err; + } + + gpio->gpio.label = gpio->soc->name; + gpio->gpio.parent = &pdev->dev; + + gpio->gpio.get_direction = tegra186_gpio_get_direction; + gpio->gpio.direction_input = tegra186_gpio_direction_input; + gpio->gpio.direction_output = tegra186_gpio_direction_output; + gpio->gpio.get = tegra186_gpio_get, + gpio->gpio.set = tegra186_gpio_set; + + gpio->gpio.base = -1; + + for (i = 0; i < gpio->soc->num_ports; i++) + gpio->gpio.ngpio += gpio->soc->ports[i].pins; + + names = devm_kcalloc(gpio->gpio.parent, gpio->gpio.ngpio, + sizeof(*names), GFP_KERNEL); + if (!names) + return -ENOMEM; + + for (i = 0, offset = 0; i < gpio->soc->num_ports; i++) { + const struct tegra_gpio_port *port = &gpio->soc->ports[i]; + char *name; + + for (j = 0; j < port->pins; j++) { + name = devm_kasprintf(gpio->gpio.parent, GFP_KERNEL, + "P%s.%02x", port->name, j); + if (!name) + return -ENOMEM; + + names[offset + j] = name; + } + + offset += port->pins; + } + + gpio->gpio.names = (const char * const *)names; + + gpio->gpio.of_node = pdev->dev.of_node; + gpio->gpio.of_gpio_n_cells = 2; + gpio->gpio.of_xlate = tegra186_gpio_of_xlate; + + gpio->intc.name = pdev->dev.of_node->name; + gpio->intc.irq_ack = tegra186_irq_ack; + gpio->intc.irq_mask = tegra186_irq_mask; + gpio->intc.irq_unmask = tegra186_irq_unmask; + gpio->intc.irq_set_type = tegra186_irq_set_type; + + irq = &gpio->gpio.irq; + irq->chip = &gpio->intc; + irq->first = 0; + irq->domain_ops = &tegra186_gpio_irq_domain_ops; + irq->handler = handle_simple_irq; + irq->lock_key = &tegra186_gpio_lock_class; + irq->default_type = IRQ_TYPE_NONE; + irq->parent_handler = tegra186_gpio_irq; + irq->parent_handler_data = gpio; + irq->num_parents = gpio->num_irq; + irq->parents = gpio->irq; + + irq->map = devm_kcalloc(&pdev->dev, gpio->gpio.ngpio, + sizeof(*irq->map), GFP_KERNEL); + if (!irq->map) + return -ENOMEM; + + for (i = 0, offset = 0; i < gpio->soc->num_ports; i++) { + const struct tegra_gpio_port *port = &gpio->soc->ports[i]; + + for (j = 0; j < port->pins; j++) + irq->map[offset + j] = irq->parents[port->irq]; + + offset += port->pins; + } + + platform_set_drvdata(pdev, gpio); + + err = devm_gpiochip_add_data(&pdev->dev, &gpio->gpio, gpio); + if (err < 0) + return err; + + return 0; +} + +static int tegra186_gpio_remove(struct platform_device *pdev) +{ + return 0; +} + +#define TEGRA_MAIN_GPIO_PORT(port, base, count, controller) \ + [TEGRA_MAIN_GPIO_PORT_##port] = { \ + .name = #port, \ + .offset = base, \ + .pins = count, \ + .irq = controller, \ + } + +static const struct tegra_gpio_port tegra186_main_ports[] = { + TEGRA_MAIN_GPIO_PORT( A, 0x2000, 7, 2), + TEGRA_MAIN_GPIO_PORT( B, 0x3000, 7, 3), + TEGRA_MAIN_GPIO_PORT( C, 0x3200, 7, 3), + TEGRA_MAIN_GPIO_PORT( D, 0x3400, 6, 3), + TEGRA_MAIN_GPIO_PORT( E, 0x2200, 8, 2), + TEGRA_MAIN_GPIO_PORT( F, 0x2400, 6, 2), + TEGRA_MAIN_GPIO_PORT( G, 0x4200, 6, 4), + TEGRA_MAIN_GPIO_PORT( H, 0x1000, 7, 1), + TEGRA_MAIN_GPIO_PORT( I, 0x0800, 8, 0), + TEGRA_MAIN_GPIO_PORT( J, 0x5000, 8, 5), + TEGRA_MAIN_GPIO_PORT( K, 0x5200, 1, 5), + TEGRA_MAIN_GPIO_PORT( L, 0x1200, 8, 1), + TEGRA_MAIN_GPIO_PORT( M, 0x5600, 6, 5), + TEGRA_MAIN_GPIO_PORT( N, 0x0000, 7, 0), + TEGRA_MAIN_GPIO_PORT( O, 0x0200, 4, 0), + TEGRA_MAIN_GPIO_PORT( P, 0x4000, 7, 4), + TEGRA_MAIN_GPIO_PORT( Q, 0x0400, 6, 0), + TEGRA_MAIN_GPIO_PORT( R, 0x0a00, 6, 0), + TEGRA_MAIN_GPIO_PORT( T, 0x0600, 4, 0), + TEGRA_MAIN_GPIO_PORT( X, 0x1400, 8, 1), + TEGRA_MAIN_GPIO_PORT( Y, 0x1600, 7, 1), + TEGRA_MAIN_GPIO_PORT(BB, 0x2600, 2, 2), + TEGRA_MAIN_GPIO_PORT(CC, 0x5400, 4, 5), +}; + +static const struct tegra_gpio_soc tegra186_main_soc = { + .num_ports = ARRAY_SIZE(tegra186_main_ports), + .ports = tegra186_main_ports, + .name = "tegra186-gpio", +}; + +#define TEGRA_AON_GPIO_PORT(port, base, count, controller) \ + [TEGRA_AON_GPIO_PORT_##port] = { \ + .name = #port, \ + .offset = base, \ + .pins = count, \ + .irq = controller, \ + } + +static const struct tegra_gpio_port tegra186_aon_ports[] = { + TEGRA_AON_GPIO_PORT( S, 0x0200, 5, 0), + TEGRA_AON_GPIO_PORT( U, 0x0400, 6, 0), + TEGRA_AON_GPIO_PORT( V, 0x0800, 8, 0), + TEGRA_AON_GPIO_PORT( W, 0x0a00, 8, 0), + TEGRA_AON_GPIO_PORT( Z, 0x0e00, 4, 0), + TEGRA_AON_GPIO_PORT(AA, 0x0c00, 8, 0), + TEGRA_AON_GPIO_PORT(EE, 0x0600, 3, 0), + TEGRA_AON_GPIO_PORT(FF, 0x0000, 5, 0), +}; + +static const struct tegra_gpio_soc tegra186_aon_soc = { + .num_ports = ARRAY_SIZE(tegra186_aon_ports), + .ports = tegra186_aon_ports, + .name = "tegra186-gpio-aon", +}; + +static const struct of_device_id tegra186_gpio_of_match[] = { + { + .compatible = "nvidia,tegra186-gpio", + .data = &tegra186_main_soc + }, { + .compatible = "nvidia,tegra186-gpio-aon", + .data = &tegra186_aon_soc + }, { + /* sentinel */ + } +}; + +static struct platform_driver tegra186_gpio_driver = { + .driver = { + .name = "tegra186-gpio", + .of_match_table = tegra186_gpio_of_match, + }, + .probe = tegra186_gpio_probe, + .remove = tegra186_gpio_remove, +}; +module_platform_driver(tegra186_gpio_driver); + +MODULE_DESCRIPTION("NVIDIA Tegra186 GPIO controller driver"); +MODULE_AUTHOR("Thierry Reding "); +MODULE_LICENSE("GPL v2"); From patchwork Fri Sep 1 18:57:32 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Reding X-Patchwork-Id: 808958 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="WiD4F1l2"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3xkT7Y2DRPz9sQl for ; Sat, 2 Sep 2017 04:59:37 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752312AbdIAS6E (ORCPT ); Fri, 1 Sep 2017 14:58:04 -0400 Received: from mail-wm0-f67.google.com ([74.125.82.67]:33748 "EHLO mail-wm0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752547AbdIAS6C (ORCPT ); Fri, 1 Sep 2017 14:58:02 -0400 Received: by mail-wm0-f67.google.com with SMTP id 187so742081wmn.0; Fri, 01 Sep 2017 11:58:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=A5tx/mHrm1dZazNGCfri1ib4FAyvHeEG5vQ3Tji7RGk=; b=WiD4F1l2PpRM7MFujeI7YmccQu53K4Yjljn/A2YmxpfatiZtH+XmId+U2ghUFg0tpP ihDFaw8aTvixp7NdSqXRabAT6rMqGMfeKQ0OmRL33Bwt9C1UbcXQFU1wOwCen4/43f5x HJ0cwdDSxlH0DXrFw0T64XWUleh1mgDx2bP34U+1GPDrEagcivAmLHfIOy3Re4Xb80HU FsLWkKcZbCQ8aLqRzH0v8Nw4Bzoa1mzoA5nT7ftQvCQj0o2vLTt5SPE6RxpyGexey3ZN vQbDZTtj3y1rAK6QLiPrWW0aT7Cc96/6Myiwdt0b5qRhm6odyfs2KzTuLbEQQJG//3cR PeRQ== 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=A5tx/mHrm1dZazNGCfri1ib4FAyvHeEG5vQ3Tji7RGk=; b=HQIM4iKQ5epTQfHIagsaOIFd1YIQU9PUi9VcEwKgA5tdAds79EPj/sX6eeQSYe0gq2 0YgT2uDx6ARZAqteBRtSn2EbUVqSIx3q3IH1UX5LshbKh90U36CKSohHbmFc3fvlyeH2 yP/JAeeXbHD1WoCBhehkF3ncjwY7PWdiVV3u4nqn4aVymSBtmnP0dwVHP890vhW1a7iS fXFxOvT3J790Mbk1aJX/CkixRaaTA+pUlL1eypWg97SR//95hdZO58UuChEY/9Xne35r mTeV4SIPZIp8UQxB9d1p6VGIezE5+R0Z8L39kOlDOkNdpGSYiebB7HeYew0//Up1tlnl 61xA== X-Gm-Message-State: AHPjjUi064maN57Ud5syDZU4INSlwww35pgHSim4+UaFWflFRNQOpn83 pMa9bsLWtKgD+Q== X-Google-Smtp-Source: ADKCNb5iRisDzZqU6/mVmau8OUqkJBkR1QYzIWyuMMSDuBJnBhvrAanJSjESrVFFG75I3+gaZRQ9Ww== X-Received: by 10.28.73.212 with SMTP id w203mr946669wma.53.1504292280469; Fri, 01 Sep 2017 11:58:00 -0700 (PDT) Received: from localhost (p200300E41BD6D60076D02BFFFE273F51.dip0.t-ipconnect.de. [2003:e4:1bd6:d600:76d0:2bff:fe27:3f51]) by smtp.gmail.com with ESMTPSA id v2sm573566wrd.68.2017.09.01.11.57.59 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 01 Sep 2017 11:57:59 -0700 (PDT) From: Thierry Reding To: Linus Walleij Cc: Jonathan Hunter , linux-gpio@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 12/16] gpio: omap: Fix checkpatch warnings Date: Fri, 1 Sep 2017 20:57:32 +0200 Message-Id: <20170901185736.28051-13-thierry.reding@gmail.com> X-Mailer: git-send-email 2.13.3 In-Reply-To: <20170901185736.28051-1-thierry.reding@gmail.com> References: <20170901185736.28051-1-thierry.reding@gmail.com> Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Thierry Reding Use unsigned int rather than unsigned, wrap lines longer than 80 characters and other minor coding style cleanups. Signed-off-by: Thierry Reding Acked-by: Grygorii Strashko --- drivers/gpio/gpio-omap.c | 113 ++++++++++++++++++++++++++--------------------- 1 file changed, 63 insertions(+), 50 deletions(-) diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index ce27d6a586bf..7c600cec3e44 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -76,7 +76,8 @@ struct gpio_bank { int power_mode; bool workaround_enabled; - void (*set_dataout)(struct gpio_bank *bank, unsigned gpio, int enable); + void (*set_dataout)(struct gpio_bank *bank, unsigned int gpio, + int enable); int (*get_context_loss_count)(struct device *dev); struct omap_gpio_reg_offs *regs; @@ -92,6 +93,7 @@ static void omap_gpio_unmask_irq(struct irq_data *d); static inline struct gpio_bank *omap_irq_data_get_bank(struct irq_data *d) { struct gpio_chip *chip = irq_data_get_irq_chip_data(d); + return gpiochip_get_data(chip); } @@ -113,8 +115,8 @@ static void omap_set_gpio_direction(struct gpio_bank *bank, int gpio, /* set data out value using dedicate set/clear register */ -static void omap_set_gpio_dataout_reg(struct gpio_bank *bank, unsigned offset, - int enable) +static void omap_set_gpio_dataout_reg(struct gpio_bank *bank, + unsigned int offset, int enable) { void __iomem *reg = bank->base; u32 l = BIT(offset); @@ -131,8 +133,8 @@ static void omap_set_gpio_dataout_reg(struct gpio_bank *bank, unsigned offset, } /* set data out value using mask register */ -static void omap_set_gpio_dataout_mask(struct gpio_bank *bank, unsigned offset, - int enable) +static void omap_set_gpio_dataout_mask(struct gpio_bank *bank, + unsigned int offset, int enable) { void __iomem *reg = bank->base + bank->regs->dataout; u32 gpio_bit = BIT(offset); @@ -161,7 +163,8 @@ static int omap_get_gpio_dataout(struct gpio_bank *bank, int offset) return (readl_relaxed(reg) & (BIT(offset))) != 0; } -static inline void omap_gpio_rmw(void __iomem *base, u32 reg, u32 mask, bool set) +static inline void omap_gpio_rmw(void __iomem *base, u32 reg, u32 mask, + bool set) { int l = readl_relaxed(base + reg); @@ -211,8 +214,8 @@ static inline void omap_gpio_dbck_disable(struct gpio_bank *bank) * * Return: 0 on success, negative error otherwise. */ -static int omap2_set_gpio_debounce(struct gpio_bank *bank, unsigned offset, - unsigned debounce) +static int omap2_set_gpio_debounce(struct gpio_bank *bank, unsigned int offset, + unsigned int debounce) { void __iomem *reg; u32 val; @@ -272,7 +275,8 @@ static int omap2_set_gpio_debounce(struct gpio_bank *bank, unsigned offset, * time too. The debounce clock will also be disabled when calling this function * if this is the only gpio in the bank using debounce. */ -static void omap_clear_gpio_debounce(struct gpio_bank *bank, unsigned offset) +static void omap_clear_gpio_debounce(struct gpio_bank *bank, + unsigned int offset) { u32 gpio_bit = BIT(offset); @@ -284,8 +288,8 @@ static void omap_clear_gpio_debounce(struct gpio_bank *bank, unsigned offset) bank->dbck_enable_mask &= ~gpio_bit; bank->context.debounce_en &= ~gpio_bit; - writel_relaxed(bank->context.debounce_en, - bank->base + bank->regs->debounce_en); + writel_relaxed(bank->context.debounce_en, + bank->base + bank->regs->debounce_en); if (!bank->dbck_enable_mask) { bank->context.debounce = 0; @@ -297,7 +301,7 @@ static void omap_clear_gpio_debounce(struct gpio_bank *bank, unsigned offset) } static inline void omap_set_gpio_trigger(struct gpio_bank *bank, int gpio, - unsigned trigger) + unsigned int trigger) { void __iomem *base = bank->base; u32 gpio_bit = BIT(gpio); @@ -321,7 +325,8 @@ static inline void omap_set_gpio_trigger(struct gpio_bank *bank, int gpio, readl_relaxed(bank->base + bank->regs->fallingdetect); if (likely(!(bank->non_wakeup_gpios & gpio_bit))) { - omap_gpio_rmw(base, bank->regs->wkup_en, gpio_bit, trigger != 0); + omap_gpio_rmw(base, bank->regs->wkup_en, gpio_bit, + trigger != 0); bank->context.wake_en = readl_relaxed(bank->base + bank->regs->wkup_en); } @@ -376,11 +381,13 @@ static void omap_toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio) writel_relaxed(l, reg); } #else -static void omap_toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio) {} +static void omap_toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio) +{ +} #endif static int omap_set_gpio_triggering(struct gpio_bank *bank, int gpio, - unsigned trigger) + unsigned int trigger) { void __iomem *reg = bank->base; void __iomem *base = bank->base; @@ -425,7 +432,7 @@ static int omap_set_gpio_triggering(struct gpio_bank *bank, int gpio, return 0; } -static void omap_enable_gpio_module(struct gpio_bank *bank, unsigned offset) +static void omap_enable_gpio_module(struct gpio_bank *bank, unsigned int offset) { if (bank->regs->pinctrl) { void __iomem *reg = bank->base + bank->regs->pinctrl; @@ -446,7 +453,8 @@ static void omap_enable_gpio_module(struct gpio_bank *bank, unsigned offset) } } -static void omap_disable_gpio_module(struct gpio_bank *bank, unsigned offset) +static void omap_disable_gpio_module(struct gpio_bank *bank, + unsigned int offset) { void __iomem *base = bank->base; @@ -471,14 +479,14 @@ static void omap_disable_gpio_module(struct gpio_bank *bank, unsigned offset) } } -static int omap_gpio_is_input(struct gpio_bank *bank, unsigned offset) +static int omap_gpio_is_input(struct gpio_bank *bank, unsigned int offset) { void __iomem *reg = bank->base + bank->regs->direction; return readl_relaxed(reg) & BIT(offset); } -static void omap_gpio_init_irq(struct gpio_bank *bank, unsigned offset) +static void omap_gpio_init_irq(struct gpio_bank *bank, unsigned int offset) { if (!LINE_USED(bank->mod_usage, offset)) { omap_enable_gpio_module(bank, offset); @@ -487,12 +495,12 @@ static void omap_gpio_init_irq(struct gpio_bank *bank, unsigned offset) bank->irq_usage |= BIT(offset); } -static int omap_gpio_irq_type(struct irq_data *d, unsigned type) +static int omap_gpio_irq_type(struct irq_data *d, unsigned int type) { struct gpio_bank *bank = omap_irq_data_get_bank(d); int retval; unsigned long flags; - unsigned offset = d->hwirq; + unsigned int offset = d->hwirq; if (type & ~IRQ_TYPE_SENSE_MASK) return -EINVAL; @@ -544,7 +552,7 @@ static void omap_clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) } static inline void omap_clear_gpio_irqstatus(struct gpio_bank *bank, - unsigned offset) + unsigned int offset) { omap_clear_gpio_irqbank(bank, BIT(offset)); } @@ -608,7 +616,7 @@ static void omap_disable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) } static inline void omap_set_gpio_irqenable(struct gpio_bank *bank, - unsigned offset, int enable) + unsigned int offset, int enable) { if (enable) omap_enable_gpio_irqbank(bank, BIT(offset)); @@ -624,7 +632,7 @@ static int omap_gpio_wake_enable(struct irq_data *d, unsigned int enable) return irq_set_irq_wake(bank->irq, enable); } -static int omap_gpio_request(struct gpio_chip *chip, unsigned offset) +static int omap_gpio_request(struct gpio_chip *chip, unsigned int offset) { struct gpio_bank *bank = gpiochip_get_data(chip); unsigned long flags; @@ -644,7 +652,7 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned offset) return 0; } -static void omap_gpio_free(struct gpio_chip *chip, unsigned offset) +static void omap_gpio_free(struct gpio_chip *chip, unsigned int offset) { struct gpio_bank *bank = gpiochip_get_data(chip); unsigned long flags; @@ -702,9 +710,11 @@ static irqreturn_t omap_gpio_irq_handler(int irq, void *gpiobank) if (bank->level_mask) level_mask = bank->level_mask & enabled; - /* clear edge sensitive interrupts before handler(s) are - called so that we don't miss any interrupt occurred while - executing them */ + /* + * clear edge sensitive interrupts before handler(s) are + * called so that we don't miss any interrupt occurred while + * executing them + */ omap_disable_gpio_irqbank(bank, isr_saved & ~level_mask); omap_clear_gpio_irqbank(bank, isr_saved & ~level_mask); omap_enable_gpio_irqbank(bank, isr_saved & ~level_mask); @@ -715,6 +725,8 @@ static irqreturn_t omap_gpio_irq_handler(int irq, void *gpiobank) break; while (isr) { + unsigned int irq; + bit = __ffs(isr); isr &= ~(BIT(bit)); @@ -733,8 +745,8 @@ static irqreturn_t omap_gpio_irq_handler(int irq, void *gpiobank) raw_spin_lock_irqsave(&bank->wa_lock, wa_lock_flags); - generic_handle_irq(irq_find_mapping(bank->chip.irq.domain, - bit)); + irq = irq_find_mapping(bank->chip.irq.domain, bit); + generic_handle_irq(irq); raw_spin_unlock_irqrestore(&bank->wa_lock, wa_lock_flags); @@ -749,7 +761,7 @@ static unsigned int omap_gpio_irq_startup(struct irq_data *d) { struct gpio_bank *bank = omap_irq_data_get_bank(d); unsigned long flags; - unsigned offset = d->hwirq; + unsigned int offset = d->hwirq; raw_spin_lock_irqsave(&bank->lock, flags); @@ -773,7 +785,7 @@ static void omap_gpio_irq_shutdown(struct irq_data *d) { struct gpio_bank *bank = omap_irq_data_get_bank(d); unsigned long flags; - unsigned offset = d->hwirq; + unsigned int offset = d->hwirq; raw_spin_lock_irqsave(&bank->lock, flags); bank->irq_usage &= ~(BIT(offset)); @@ -809,7 +821,7 @@ static void gpio_irq_bus_sync_unlock(struct irq_data *data) static void omap_gpio_ack_irq(struct irq_data *d) { struct gpio_bank *bank = omap_irq_data_get_bank(d); - unsigned offset = d->hwirq; + unsigned int offset = d->hwirq; omap_clear_gpio_irqstatus(bank, offset); } @@ -817,7 +829,7 @@ static void omap_gpio_ack_irq(struct irq_data *d) static void omap_gpio_mask_irq(struct irq_data *d) { struct gpio_bank *bank = omap_irq_data_get_bank(d); - unsigned offset = d->hwirq; + unsigned int offset = d->hwirq; unsigned long flags; raw_spin_lock_irqsave(&bank->lock, flags); @@ -829,7 +841,7 @@ static void omap_gpio_mask_irq(struct irq_data *d) static void omap_gpio_unmask_irq(struct irq_data *d) { struct gpio_bank *bank = omap_irq_data_get_bank(d); - unsigned offset = d->hwirq; + unsigned int offset = d->hwirq; u32 trigger = irqd_get_trigger_type(d); unsigned long flags; @@ -837,8 +849,10 @@ static void omap_gpio_unmask_irq(struct irq_data *d) if (trigger) omap_set_gpio_triggering(bank, offset, trigger); - /* For level-triggered GPIOs, the clearing must be done after - * the HW source is cleared, thus after the handler has run */ + /* + * For level-triggered GPIOs, the clearing must be done after + * the HW source is cleared, thus after the handler has run + */ if (bank->level_mask & BIT(offset)) { omap_set_gpio_irqenable(bank, offset, 0); omap_clear_gpio_irqstatus(bank, offset); @@ -912,7 +926,7 @@ static inline void omap_mpuio_init(struct gpio_bank *bank) /*---------------------------------------------------------------------*/ -static int omap_gpio_get_direction(struct gpio_chip *chip, unsigned offset) +static int omap_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) { struct gpio_bank *bank; unsigned long flags; @@ -927,7 +941,7 @@ static int omap_gpio_get_direction(struct gpio_chip *chip, unsigned offset) return dir; } -static int omap_gpio_input(struct gpio_chip *chip, unsigned offset) +static int omap_gpio_input(struct gpio_chip *chip, unsigned int offset) { struct gpio_bank *bank; unsigned long flags; @@ -939,7 +953,7 @@ static int omap_gpio_input(struct gpio_chip *chip, unsigned offset) return 0; } -static int omap_gpio_get(struct gpio_chip *chip, unsigned offset) +static int omap_gpio_get(struct gpio_chip *chip, unsigned int offset) { struct gpio_bank *bank; @@ -951,7 +965,8 @@ static int omap_gpio_get(struct gpio_chip *chip, unsigned offset) return omap_get_gpio_dataout(bank, offset); } -static int omap_gpio_output(struct gpio_chip *chip, unsigned offset, int value) +static int omap_gpio_output(struct gpio_chip *chip, unsigned int offset, + int value) { struct gpio_bank *bank; unsigned long flags; @@ -964,8 +979,8 @@ static int omap_gpio_output(struct gpio_chip *chip, unsigned offset, int value) return 0; } -static int omap_gpio_debounce(struct gpio_chip *chip, unsigned offset, - unsigned debounce) +static int omap_gpio_debounce(struct gpio_chip *chip, unsigned int offset, + unsigned int debounce) { struct gpio_bank *bank; unsigned long flags; @@ -985,7 +1000,7 @@ static int omap_gpio_debounce(struct gpio_chip *chip, unsigned offset, return ret; } -static int omap_gpio_set_config(struct gpio_chip *chip, unsigned offset, +static int omap_gpio_set_config(struct gpio_chip *chip, unsigned int offset, unsigned long config) { u32 debounce; @@ -997,7 +1012,8 @@ static int omap_gpio_set_config(struct gpio_chip *chip, unsigned offset, return omap_gpio_debounce(chip, offset, debounce); } -static void omap_gpio_set(struct gpio_chip *chip, unsigned offset, int value) +static void omap_gpio_set(struct gpio_chip *chip, unsigned int offset, + int value) { struct gpio_bank *bank; unsigned long flags; @@ -1153,10 +1169,8 @@ static int omap_gpio_probe(struct platform_device *pdev) return -EINVAL; bank = devm_kzalloc(dev, sizeof(struct gpio_bank), GFP_KERNEL); - if (!bank) { - dev_err(dev, "Memory alloc failed\n"); + if (!bank) return -ENOMEM; - } irqc = devm_kzalloc(dev, sizeof(*irqc), GFP_KERNEL); if (!irqc) @@ -1217,9 +1231,8 @@ static int omap_gpio_probe(struct platform_device *pdev) /* Static mapping, never released */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); bank->base = devm_ioremap_resource(dev, res); - if (IS_ERR(bank->base)) { + if (IS_ERR(bank->base)) return PTR_ERR(bank->base); - } if (bank->dbck_flag) { bank->dbck = devm_clk_get(dev, "dbclk"); From patchwork Fri Sep 1 18:57:33 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Reding X-Patchwork-Id: 808959 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="K5fV5WeI"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3xkT7w1chgz9sQl for ; Sat, 2 Sep 2017 04:59:56 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752687AbdIAS7k (ORCPT ); Fri, 1 Sep 2017 14:59:40 -0400 Received: from mail-wr0-f194.google.com ([209.85.128.194]:36042 "EHLO mail-wr0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752548AbdIAS6E (ORCPT ); Fri, 1 Sep 2017 14:58:04 -0400 Received: by mail-wr0-f194.google.com with SMTP id 40so484930wrv.3; Fri, 01 Sep 2017 11:58:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=TPmT+PQaTHNRNnzg4Grk2xv06kp4ckEnPFADDqRy3b4=; b=K5fV5WeIF/vyAqK3IfpBXcVKOpEMvP+DD9xAnXXDVo5vpMTNs4eGoIJFOMQmWrJ0sN zJs1LyrEnkBNfLEg83IupsJe4bcAfYbSyxca1+8C8/M7TbOFbSL/hdGD7FSCDDixa54m rCkbqN1gvxATyY0Fmj+F1K2jNVGeM2onjF5rk3Ii0TCRFXaTzy3eWBFqpdpw2E+qvNON LgwYVuTUz1/h/SgYbNO+RTI4LSEvG2qBzYpgYXqwTdlOybg2io4UElnZXQ5LPKc8NXF6 koG1UX/GezbNs/fKgnfn3362JH+KvEq9kxcJ5apKL5+6RTOrjdLTgqctDVdL9MlzdXW2 +dVg== 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=TPmT+PQaTHNRNnzg4Grk2xv06kp4ckEnPFADDqRy3b4=; b=m38IYB+N6LA6IvxKjahUf50I+GjAGsHoSa2BESxukCSBlTBiHO3DKmvuHGBcGSMPHp HffwhOcM1bvJLgx3kOO1BTekPE1AI+DROSs9nlp/PQLASKKAcBaCXvXRVg3DeTzSWkHu eEIq6K2shVsk4bKfnYZ2PgQOlqcv4Cn6v8BBadOzKkV3BCQp2wSLKtSregEoONz4MvAg rJcOPuWtQR4FFtNG+PG0fYsrYm3u26r6NRe1y6RZbD0grBMQl68CBss1ai8Lb7+GHOmj ossp1mdyvRYsOZYM9daduStCaNuJfdjAroUoCBG/7Ojfm9s7oI5ALe5/iZCQWICVmlKE NTNg== X-Gm-Message-State: AHPjjUjG0hImS7F1ZRL+YRNwrmOLLxHF9av45J+NgTzsMREfSIJc1roK cGv7Nlde+Ueqaw== X-Google-Smtp-Source: ADKCNb4hT1La7FSQ3ypxAllfE41jFb0elCBsIFa4eREVZk0+37Wc6Hh7HMQ4Mb5mbBYJk/H9l/IZ+g== X-Received: by 10.223.136.196 with SMTP id g4mr1771206wrg.100.1504292282023; Fri, 01 Sep 2017 11:58:02 -0700 (PDT) Received: from localhost (p200300E41BD6D60076D02BFFFE273F51.dip0.t-ipconnect.de. [2003:e4:1bd6:d600:76d0:2bff:fe27:3f51]) by smtp.gmail.com with ESMTPSA id j79sm660291wmd.20.2017.09.01.11.58.01 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 01 Sep 2017 11:58:01 -0700 (PDT) From: Thierry Reding To: Linus Walleij Cc: Jonathan Hunter , linux-gpio@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 13/16] gpio: omap: Rename struct gpio_bank to struct omap_gpio_bank Date: Fri, 1 Sep 2017 20:57:33 +0200 Message-Id: <20170901185736.28051-14-thierry.reding@gmail.com> X-Mailer: git-send-email 2.13.3 In-Reply-To: <20170901185736.28051-1-thierry.reding@gmail.com> References: <20170901185736.28051-1-thierry.reding@gmail.com> Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Thierry Reding Subsequent patches will want to introduce a struct gpio_bank in core code, so rename this to something driver-specific in order to avoid the names from clashing. Signed-off-by: Thierry Reding Acked-by: Grygorii Strashko --- drivers/gpio/gpio-omap.c | 131 ++++++++++++++++++++++++----------------------- 1 file changed, 68 insertions(+), 63 deletions(-) diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 7c600cec3e44..0b80d929d892 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c @@ -48,7 +48,7 @@ struct gpio_regs { u32 debounce_en; }; -struct gpio_bank { +struct omap_gpio_bank { struct list_head node; void __iomem *base; int irq; @@ -76,7 +76,7 @@ struct gpio_bank { int power_mode; bool workaround_enabled; - void (*set_dataout)(struct gpio_bank *bank, unsigned int gpio, + void (*set_dataout)(struct omap_gpio_bank *bank, unsigned int gpio, int enable); int (*get_context_loss_count)(struct device *dev); @@ -90,14 +90,14 @@ struct gpio_bank { static void omap_gpio_unmask_irq(struct irq_data *d); -static inline struct gpio_bank *omap_irq_data_get_bank(struct irq_data *d) +static inline struct omap_gpio_bank *omap_irq_data_get_bank(struct irq_data *d) { struct gpio_chip *chip = irq_data_get_irq_chip_data(d); return gpiochip_get_data(chip); } -static void omap_set_gpio_direction(struct gpio_bank *bank, int gpio, +static void omap_set_gpio_direction(struct omap_gpio_bank *bank, int gpio, int is_input) { void __iomem *reg = bank->base; @@ -115,7 +115,7 @@ static void omap_set_gpio_direction(struct gpio_bank *bank, int gpio, /* set data out value using dedicate set/clear register */ -static void omap_set_gpio_dataout_reg(struct gpio_bank *bank, +static void omap_set_gpio_dataout_reg(struct omap_gpio_bank *bank, unsigned int offset, int enable) { void __iomem *reg = bank->base; @@ -133,7 +133,7 @@ static void omap_set_gpio_dataout_reg(struct gpio_bank *bank, } /* set data out value using mask register */ -static void omap_set_gpio_dataout_mask(struct gpio_bank *bank, +static void omap_set_gpio_dataout_mask(struct omap_gpio_bank *bank, unsigned int offset, int enable) { void __iomem *reg = bank->base + bank->regs->dataout; @@ -149,14 +149,14 @@ static void omap_set_gpio_dataout_mask(struct gpio_bank *bank, bank->context.dataout = l; } -static int omap_get_gpio_datain(struct gpio_bank *bank, int offset) +static int omap_get_gpio_datain(struct omap_gpio_bank *bank, int offset) { void __iomem *reg = bank->base + bank->regs->datain; return (readl_relaxed(reg) & (BIT(offset))) != 0; } -static int omap_get_gpio_dataout(struct gpio_bank *bank, int offset) +static int omap_get_gpio_dataout(struct omap_gpio_bank *bank, int offset) { void __iomem *reg = bank->base + bank->regs->dataout; @@ -176,7 +176,7 @@ static inline void omap_gpio_rmw(void __iomem *base, u32 reg, u32 mask, writel_relaxed(l, base + reg); } -static inline void omap_gpio_dbck_enable(struct gpio_bank *bank) +static inline void omap_gpio_dbck_enable(struct omap_gpio_bank *bank) { if (bank->dbck_enable_mask && !bank->dbck_enabled) { clk_enable(bank->dbck); @@ -187,7 +187,7 @@ static inline void omap_gpio_dbck_enable(struct gpio_bank *bank) } } -static inline void omap_gpio_dbck_disable(struct gpio_bank *bank) +static inline void omap_gpio_dbck_disable(struct omap_gpio_bank *bank) { if (bank->dbck_enable_mask && bank->dbck_enabled) { /* @@ -214,8 +214,8 @@ static inline void omap_gpio_dbck_disable(struct gpio_bank *bank) * * Return: 0 on success, negative error otherwise. */ -static int omap2_set_gpio_debounce(struct gpio_bank *bank, unsigned int offset, - unsigned int debounce) +static int omap2_set_gpio_debounce(struct omap_gpio_bank *bank, + unsigned int offset, unsigned int debounce) { void __iomem *reg; u32 val; @@ -275,7 +275,7 @@ static int omap2_set_gpio_debounce(struct gpio_bank *bank, unsigned int offset, * time too. The debounce clock will also be disabled when calling this function * if this is the only gpio in the bank using debounce. */ -static void omap_clear_gpio_debounce(struct gpio_bank *bank, +static void omap_clear_gpio_debounce(struct omap_gpio_bank *bank, unsigned int offset) { u32 gpio_bit = BIT(offset); @@ -300,7 +300,7 @@ static void omap_clear_gpio_debounce(struct gpio_bank *bank, } } -static inline void omap_set_gpio_trigger(struct gpio_bank *bank, int gpio, +static inline void omap_set_gpio_trigger(struct omap_gpio_bank *bank, int gpio, unsigned int trigger) { void __iomem *base = bank->base; @@ -362,7 +362,8 @@ static inline void omap_set_gpio_trigger(struct gpio_bank *bank, int gpio, * This only applies to chips that can't do both rising and falling edge * detection at once. For all other chips, this function is a noop. */ -static void omap_toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio) +static void omap_toggle_gpio_edge_triggering(struct omap_gpio_bank *bank, + int gpio) { void __iomem *reg = bank->base; u32 l = 0; @@ -381,12 +382,13 @@ static void omap_toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio) writel_relaxed(l, reg); } #else -static void omap_toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio) +static void omap_toggle_gpio_edge_triggering(struct omap_gpio_bank *bank, + int gpio) { } #endif -static int omap_set_gpio_triggering(struct gpio_bank *bank, int gpio, +static int omap_set_gpio_triggering(struct omap_gpio_bank *bank, int gpio, unsigned int trigger) { void __iomem *reg = bank->base; @@ -432,7 +434,8 @@ static int omap_set_gpio_triggering(struct gpio_bank *bank, int gpio, return 0; } -static void omap_enable_gpio_module(struct gpio_bank *bank, unsigned int offset) +static void omap_enable_gpio_module(struct omap_gpio_bank *bank, + unsigned int offset) { if (bank->regs->pinctrl) { void __iomem *reg = bank->base + bank->regs->pinctrl; @@ -453,7 +456,7 @@ static void omap_enable_gpio_module(struct gpio_bank *bank, unsigned int offset) } } -static void omap_disable_gpio_module(struct gpio_bank *bank, +static void omap_disable_gpio_module(struct omap_gpio_bank *bank, unsigned int offset) { void __iomem *base = bank->base; @@ -479,14 +482,14 @@ static void omap_disable_gpio_module(struct gpio_bank *bank, } } -static int omap_gpio_is_input(struct gpio_bank *bank, unsigned int offset) +static int omap_gpio_is_input(struct omap_gpio_bank *bank, unsigned int offset) { void __iomem *reg = bank->base + bank->regs->direction; return readl_relaxed(reg) & BIT(offset); } -static void omap_gpio_init_irq(struct gpio_bank *bank, unsigned int offset) +static void omap_gpio_init_irq(struct omap_gpio_bank *bank, unsigned int offset) { if (!LINE_USED(bank->mod_usage, offset)) { omap_enable_gpio_module(bank, offset); @@ -497,7 +500,7 @@ static void omap_gpio_init_irq(struct gpio_bank *bank, unsigned int offset) static int omap_gpio_irq_type(struct irq_data *d, unsigned int type) { - struct gpio_bank *bank = omap_irq_data_get_bank(d); + struct omap_gpio_bank *bank = omap_irq_data_get_bank(d); int retval; unsigned long flags; unsigned int offset = d->hwirq; @@ -534,7 +537,7 @@ static int omap_gpio_irq_type(struct irq_data *d, unsigned int type) return retval; } -static void omap_clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) +static void omap_clear_gpio_irqbank(struct omap_gpio_bank *bank, int gpio_mask) { void __iomem *reg = bank->base; @@ -551,13 +554,13 @@ static void omap_clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) readl_relaxed(reg); } -static inline void omap_clear_gpio_irqstatus(struct gpio_bank *bank, +static inline void omap_clear_gpio_irqstatus(struct omap_gpio_bank *bank, unsigned int offset) { omap_clear_gpio_irqbank(bank, BIT(offset)); } -static u32 omap_get_gpio_irqbank_mask(struct gpio_bank *bank) +static u32 omap_get_gpio_irqbank_mask(struct omap_gpio_bank *bank) { void __iomem *reg = bank->base; u32 l; @@ -571,7 +574,7 @@ static u32 omap_get_gpio_irqbank_mask(struct gpio_bank *bank) return l; } -static void omap_enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) +static void omap_enable_gpio_irqbank(struct omap_gpio_bank *bank, int gpio_mask) { void __iomem *reg = bank->base; u32 l; @@ -593,7 +596,8 @@ static void omap_enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) writel_relaxed(l, reg); } -static void omap_disable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) +static void omap_disable_gpio_irqbank(struct omap_gpio_bank *bank, + int gpio_mask) { void __iomem *reg = bank->base; u32 l; @@ -615,7 +619,7 @@ static void omap_disable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask) writel_relaxed(l, reg); } -static inline void omap_set_gpio_irqenable(struct gpio_bank *bank, +static inline void omap_set_gpio_irqenable(struct omap_gpio_bank *bank, unsigned int offset, int enable) { if (enable) @@ -627,14 +631,14 @@ static inline void omap_set_gpio_irqenable(struct gpio_bank *bank, /* Use disable_irq_wake() and enable_irq_wake() functions from drivers */ static int omap_gpio_wake_enable(struct irq_data *d, unsigned int enable) { - struct gpio_bank *bank = omap_irq_data_get_bank(d); + struct omap_gpio_bank *bank = omap_irq_data_get_bank(d); return irq_set_irq_wake(bank->irq, enable); } static int omap_gpio_request(struct gpio_chip *chip, unsigned int offset) { - struct gpio_bank *bank = gpiochip_get_data(chip); + struct omap_gpio_bank *bank = gpiochip_get_data(chip); unsigned long flags; /* @@ -654,7 +658,7 @@ static int omap_gpio_request(struct gpio_chip *chip, unsigned int offset) static void omap_gpio_free(struct gpio_chip *chip, unsigned int offset) { - struct gpio_bank *bank = gpiochip_get_data(chip); + struct omap_gpio_bank *bank = gpiochip_get_data(chip); unsigned long flags; raw_spin_lock_irqsave(&bank->lock, flags); @@ -688,7 +692,7 @@ static irqreturn_t omap_gpio_irq_handler(int irq, void *gpiobank) void __iomem *isr_reg = NULL; u32 isr; unsigned int bit; - struct gpio_bank *bank = gpiobank; + struct omap_gpio_bank *bank = gpiobank; unsigned long wa_lock_flags; unsigned long lock_flags; @@ -759,7 +763,7 @@ static irqreturn_t omap_gpio_irq_handler(int irq, void *gpiobank) static unsigned int omap_gpio_irq_startup(struct irq_data *d) { - struct gpio_bank *bank = omap_irq_data_get_bank(d); + struct omap_gpio_bank *bank = omap_irq_data_get_bank(d); unsigned long flags; unsigned int offset = d->hwirq; @@ -783,7 +787,7 @@ static unsigned int omap_gpio_irq_startup(struct irq_data *d) static void omap_gpio_irq_shutdown(struct irq_data *d) { - struct gpio_bank *bank = omap_irq_data_get_bank(d); + struct omap_gpio_bank *bank = omap_irq_data_get_bank(d); unsigned long flags; unsigned int offset = d->hwirq; @@ -800,7 +804,7 @@ static void omap_gpio_irq_shutdown(struct irq_data *d) static void omap_gpio_irq_bus_lock(struct irq_data *data) { - struct gpio_bank *bank = omap_irq_data_get_bank(data); + struct omap_gpio_bank *bank = omap_irq_data_get_bank(data); if (!BANK_USED(bank)) pm_runtime_get_sync(bank->chip.parent); @@ -808,7 +812,7 @@ static void omap_gpio_irq_bus_lock(struct irq_data *data) static void gpio_irq_bus_sync_unlock(struct irq_data *data) { - struct gpio_bank *bank = omap_irq_data_get_bank(data); + struct omap_gpio_bank *bank = omap_irq_data_get_bank(data); /* * If this is the last IRQ to be freed in the bank, @@ -820,7 +824,7 @@ static void gpio_irq_bus_sync_unlock(struct irq_data *data) static void omap_gpio_ack_irq(struct irq_data *d) { - struct gpio_bank *bank = omap_irq_data_get_bank(d); + struct omap_gpio_bank *bank = omap_irq_data_get_bank(d); unsigned int offset = d->hwirq; omap_clear_gpio_irqstatus(bank, offset); @@ -828,7 +832,7 @@ static void omap_gpio_ack_irq(struct irq_data *d) static void omap_gpio_mask_irq(struct irq_data *d) { - struct gpio_bank *bank = omap_irq_data_get_bank(d); + struct omap_gpio_bank *bank = omap_irq_data_get_bank(d); unsigned int offset = d->hwirq; unsigned long flags; @@ -840,7 +844,7 @@ static void omap_gpio_mask_irq(struct irq_data *d) static void omap_gpio_unmask_irq(struct irq_data *d) { - struct gpio_bank *bank = omap_irq_data_get_bank(d); + struct omap_gpio_bank *bank = omap_irq_data_get_bank(d); unsigned int offset = d->hwirq; u32 trigger = irqd_get_trigger_type(d); unsigned long flags; @@ -867,7 +871,7 @@ static void omap_gpio_unmask_irq(struct irq_data *d) static int omap_mpuio_suspend_noirq(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); - struct gpio_bank *bank = platform_get_drvdata(pdev); + struct omap_gpio_bank *bank = platform_get_drvdata(pdev); void __iomem *mask_reg = bank->base + OMAP_MPUIO_GPIO_MASKIT / bank->stride; unsigned long flags; @@ -882,7 +886,7 @@ static int omap_mpuio_suspend_noirq(struct device *dev) static int omap_mpuio_resume_noirq(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); - struct gpio_bank *bank = platform_get_drvdata(pdev); + struct omap_gpio_bank *bank = platform_get_drvdata(pdev); void __iomem *mask_reg = bank->base + OMAP_MPUIO_GPIO_MASKIT / bank->stride; unsigned long flags; @@ -916,7 +920,7 @@ static struct platform_device omap_mpuio_device = { /* could list the /proc/iomem resources */ }; -static inline void omap_mpuio_init(struct gpio_bank *bank) +static inline void omap_mpuio_init(struct omap_gpio_bank *bank) { platform_set_drvdata(&omap_mpuio_device, bank); @@ -928,7 +932,7 @@ static inline void omap_mpuio_init(struct gpio_bank *bank) static int omap_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) { - struct gpio_bank *bank; + struct omap_gpio_bank *bank; unsigned long flags; void __iomem *reg; int dir; @@ -943,7 +947,7 @@ static int omap_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) static int omap_gpio_input(struct gpio_chip *chip, unsigned int offset) { - struct gpio_bank *bank; + struct omap_gpio_bank *bank; unsigned long flags; bank = gpiochip_get_data(chip); @@ -955,7 +959,7 @@ static int omap_gpio_input(struct gpio_chip *chip, unsigned int offset) static int omap_gpio_get(struct gpio_chip *chip, unsigned int offset) { - struct gpio_bank *bank; + struct omap_gpio_bank *bank; bank = gpiochip_get_data(chip); @@ -968,7 +972,7 @@ static int omap_gpio_get(struct gpio_chip *chip, unsigned int offset) static int omap_gpio_output(struct gpio_chip *chip, unsigned int offset, int value) { - struct gpio_bank *bank; + struct omap_gpio_bank *bank; unsigned long flags; bank = gpiochip_get_data(chip); @@ -982,7 +986,7 @@ static int omap_gpio_output(struct gpio_chip *chip, unsigned int offset, static int omap_gpio_debounce(struct gpio_chip *chip, unsigned int offset, unsigned int debounce) { - struct gpio_bank *bank; + struct omap_gpio_bank *bank; unsigned long flags; int ret; @@ -1015,7 +1019,7 @@ static int omap_gpio_set_config(struct gpio_chip *chip, unsigned int offset, static void omap_gpio_set(struct gpio_chip *chip, unsigned int offset, int value) { - struct gpio_bank *bank; + struct omap_gpio_bank *bank; unsigned long flags; bank = gpiochip_get_data(chip); @@ -1026,7 +1030,7 @@ static void omap_gpio_set(struct gpio_chip *chip, unsigned int offset, /*---------------------------------------------------------------------*/ -static void __init omap_gpio_show_rev(struct gpio_bank *bank) +static void __init omap_gpio_show_rev(struct omap_gpio_bank *bank) { static bool called; u32 rev; @@ -1041,7 +1045,7 @@ static void __init omap_gpio_show_rev(struct gpio_bank *bank) called = true; } -static void omap_gpio_mod_init(struct gpio_bank *bank) +static void omap_gpio_mod_init(struct omap_gpio_bank *bank) { void __iomem *base = bank->base; u32 l = 0xffffffff; @@ -1068,7 +1072,8 @@ static void omap_gpio_mod_init(struct gpio_bank *bank) writel_relaxed(0, base + bank->regs->ctrl); } -static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc) +static int omap_gpio_chip_init(struct omap_gpio_bank *bank, + struct irq_chip *irqc) { static int gpio; int irq_base = 0; @@ -1158,7 +1163,7 @@ static int omap_gpio_probe(struct platform_device *pdev) const struct of_device_id *match; const struct omap_gpio_platform_data *pdata; struct resource *res; - struct gpio_bank *bank; + struct omap_gpio_bank *bank; struct irq_chip *irqc; int ret; @@ -1168,7 +1173,7 @@ static int omap_gpio_probe(struct platform_device *pdev) if (!pdata) return -EINVAL; - bank = devm_kzalloc(dev, sizeof(struct gpio_bank), GFP_KERNEL); + bank = devm_kzalloc(dev, sizeof(struct omap_gpio_bank), GFP_KERNEL); if (!bank) return -ENOMEM; @@ -1276,7 +1281,7 @@ static int omap_gpio_probe(struct platform_device *pdev) static int omap_gpio_remove(struct platform_device *pdev) { - struct gpio_bank *bank = platform_get_drvdata(pdev); + struct omap_gpio_bank *bank = platform_get_drvdata(pdev); list_del(&bank->node); gpiochip_remove(&bank->chip); @@ -1290,12 +1295,12 @@ static int omap_gpio_remove(struct platform_device *pdev) #ifdef CONFIG_ARCH_OMAP2PLUS #if defined(CONFIG_PM) -static void omap_gpio_restore_context(struct gpio_bank *bank); +static void omap_gpio_restore_context(struct omap_gpio_bank *bank); static int omap_gpio_runtime_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); - struct gpio_bank *bank = platform_get_drvdata(pdev); + struct omap_gpio_bank *bank = platform_get_drvdata(pdev); u32 l1 = 0, l2 = 0; unsigned long flags; u32 wake_low, wake_hi; @@ -1358,12 +1363,12 @@ static int omap_gpio_runtime_suspend(struct device *dev) return 0; } -static void omap_gpio_init_context(struct gpio_bank *p); +static void omap_gpio_init_context(struct omap_gpio_bank *p); static int omap_gpio_runtime_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); - struct gpio_bank *bank = platform_get_drvdata(pdev); + struct omap_gpio_bank *bank = platform_get_drvdata(pdev); u32 l = 0, gen, gen0, gen1; unsigned long flags; int c; @@ -1475,7 +1480,7 @@ static int omap_gpio_runtime_resume(struct device *dev) #if IS_BUILTIN(CONFIG_GPIO_OMAP) void omap2_gpio_prepare_for_idle(int pwr_mode) { - struct gpio_bank *bank; + struct omap_gpio_bank *bank; list_for_each_entry(bank, &omap_gpio_list, node) { if (!BANK_USED(bank) || !bank->loses_context) @@ -1489,7 +1494,7 @@ void omap2_gpio_prepare_for_idle(int pwr_mode) void omap2_gpio_resume_after_idle(void) { - struct gpio_bank *bank; + struct omap_gpio_bank *bank; list_for_each_entry(bank, &omap_gpio_list, node) { if (!BANK_USED(bank) || !bank->loses_context) @@ -1501,7 +1506,7 @@ void omap2_gpio_resume_after_idle(void) #endif #if defined(CONFIG_PM) -static void omap_gpio_init_context(struct gpio_bank *p) +static void omap_gpio_init_context(struct omap_gpio_bank *p) { struct omap_gpio_reg_offs *regs = p->regs; void __iomem *base = p->base; @@ -1524,7 +1529,7 @@ static void omap_gpio_init_context(struct gpio_bank *p) p->context_valid = true; } -static void omap_gpio_restore_context(struct gpio_bank *bank) +static void omap_gpio_restore_context(struct omap_gpio_bank *bank) { writel_relaxed(bank->context.wake_en, bank->base + bank->regs->wkup_en); @@ -1561,7 +1566,7 @@ static void omap_gpio_restore_context(struct gpio_bank *bank) #else #define omap_gpio_runtime_suspend NULL #define omap_gpio_runtime_resume NULL -static inline void omap_gpio_init_context(struct gpio_bank *p) {} +static inline void omap_gpio_init_context(struct omap_gpio_bank *p) {} #endif static const struct dev_pm_ops gpio_pm_ops = { From patchwork Fri Sep 1 18:57:34 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Reding X-Patchwork-Id: 808956 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="rrSzEnuy"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3xkT7R3bQsz9sPm for ; Sat, 2 Sep 2017 04:59:31 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752664AbdIAS7R (ORCPT ); Fri, 1 Sep 2017 14:59:17 -0400 Received: from mail-wm0-f67.google.com ([74.125.82.67]:33769 "EHLO mail-wm0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752549AbdIAS6F (ORCPT ); Fri, 1 Sep 2017 14:58:05 -0400 Received: by mail-wm0-f67.google.com with SMTP id 187so742196wmn.0; Fri, 01 Sep 2017 11:58:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=tSuOz+0X/Nt4eZ9r+H9vcDH+vQ1IsOrt+xO/5ascoCw=; b=rrSzEnuyHlZjkPmzvX8pCIWuSev0l6/Px4eFP/gz1eKPj/z1YKnpVfr+j/cr+gbGn/ GdQm8ygWNT0rySOoH4NuQoylAM8o77NOLa/O9xLklpP9a2hwhLxJvRsIEU4eVW/HHo+B Hp/PA2eAT/XnO4Oo1HnHrVivYHDrolo2+2v/Rvqv1YbOj1YQZPauz0Bm14BLGy4XffO0 Jrhsf/OlXIMqAfd+vy/MaWVzkMOQoK1aN2lNO/4rnxGe6q4buolRek6Ydlt1OCB4rd36 LoEhQKM4LMnm9WyOlaR5B/EtuzZD2AUwQEzpH+akmZcyZiKyLJwG0pXCn5ukHoJI7g8J on2g== 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=tSuOz+0X/Nt4eZ9r+H9vcDH+vQ1IsOrt+xO/5ascoCw=; b=GoigUByGxVgPfotQtHdpmOff2N6aM/J5YaWQAW5KG17O+Xq1rZ/nD/YJcTVNXM9usJ 9kBBJRJ4yvG5x6bEdDG79vJHSudEXsIabY36V311s/wFSTYTiNH9j1cZdKhwdjRWlxUs WKtIz4+JHLh3uWicfSo0AlDTAI/WQ1XM5sB/gtNk+++bd5YEXJwtQKnWCq1mwgPVYXjQ wVGJ1DhfDhWySPn2qk17V+LYtyPNFv97k8362tpNwKteJtnUEhIuNf95cCoshCnFipqs o3Jsh8CbwXNpz9H+X2BKlz5/rlLgF+r4tfA/KAD/RUTqtY43SnM2l6/Wu3KInMNnE7Zo RxFA== X-Gm-Message-State: AHPjjUjPCtPrg8lOg3A6EaQ77KmSFTztrZH7oNUdR91Wl+VVPRgJ9Lkw Ov6Ly0rUi58du739 X-Google-Smtp-Source: ADKCNb5G2u5Mj/PNvFEcxwvpybuskWTmXxaLXMo/ISFIR7X+3516YbKK4N6Q+OVtKvmXobYTJSWF7g== X-Received: by 10.28.31.214 with SMTP id f205mr1144194wmf.139.1504292283892; Fri, 01 Sep 2017 11:58:03 -0700 (PDT) Received: from localhost (p200300E41BD6D60076D02BFFFE273F51.dip0.t-ipconnect.de. [2003:e4:1bd6:d600:76d0:2bff:fe27:3f51]) by smtp.gmail.com with ESMTPSA id k18sm708398wmd.19.2017.09.01.11.58.02 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 01 Sep 2017 11:58:02 -0700 (PDT) From: Thierry Reding To: Linus Walleij Cc: Jonathan Hunter , linux-gpio@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 14/16] gpio: Add support for banked GPIO controllers Date: Fri, 1 Sep 2017 20:57:34 +0200 Message-Id: <20170901185736.28051-15-thierry.reding@gmail.com> X-Mailer: git-send-email 2.13.3 In-Reply-To: <20170901185736.28051-1-thierry.reding@gmail.com> References: <20170901185736.28051-1-thierry.reding@gmail.com> Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Thierry Reding Some GPIO controllers are subdivided into multiple logical blocks called banks (or ports). This is often caused by the design assigning separate resources, such as register regions or interrupts, to each bank, or some set of banks. This commit adds support for describing controllers that have such a banked design and provides common code for dealing with them. Signed-off-by: Thierry Reding --- drivers/gpio/gpiolib-of.c | 101 +++++++++++++++++++++++++++++++++++++++++ drivers/gpio/gpiolib.c | 98 ++++++++++++++++++++++++++++++++++++++++ include/linux/gpio/driver.h | 108 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/of_gpio.h | 10 ++++ 4 files changed, 317 insertions(+) diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index bfcd20699ec8..8b89f03076c2 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -310,6 +310,107 @@ int of_gpio_simple_xlate(struct gpio_chip *gc, EXPORT_SYMBOL(of_gpio_simple_xlate); /** + * gpio_banked_irq_domain_xlate - decode an IRQ specifier for banked chips + * @domain: IRQ domain + * @np: device tree node + * @spec: IRQ specifier + * @size: number of cells in IRQ specifier + * @hwirq: return location for the hardware IRQ number + * @type: return location for the IRQ type + * + * Translates the IRQ specifier found in device tree into a hardware IRQ + * number and an interrupt type. + * + * Returns: + * 0 on success or a negative error code on failure. + */ +int gpio_banked_irq_domain_xlate(struct irq_domain *domain, + struct device_node *np, + const u32 *spec, unsigned int size, + unsigned long *hwirq, + unsigned int *type) +{ + struct gpio_chip *gc = domain->host_data; + unsigned int bank, pin, i, offset = 0; + + if (size < 2) + return -EINVAL; + + bank = (spec[0] >> gc->of_gpio_bank_mask) & gc->of_gpio_bank_shift; + pin = (spec[0] >> gc->of_gpio_pin_mask) & gc->of_gpio_pin_shift; + + if (bank >= gc->num_banks) { + dev_err(gc->parent, "invalid bank number: %u\n", bank); + return -EINVAL; + } + + if (pin >= gc->banks[bank]->num_pins) { + dev_err(gc->parent, "invalid pin number: %u\n", pin); + return -EINVAL; + } + + for (i = 0; i < bank; i++) + offset += gc->banks[i]->num_pins; + + *type = spec[1] & IRQ_TYPE_SENSE_MASK; + *hwirq = offset + pin; + + return 0; +} +EXPORT_SYMBOL_GPL(gpio_banked_irq_domain_xlate); + +/** + * of_gpio_banked_xlate - translate GPIO specifier to a GPIO number and flags + * @gc: GPIO chip + * @gpiospec: GPIO specifier + * @flags: return location for flags parsed from the GPIO specifier + * + * This translation function takes into account multiple banks that can make + * up a single controller. Each bank can contain one or more pins. A single + * cell in the specifier is used to represent a (bank, pin) pair, with each + * encoded in different fields. The &gpio_chip.of_gpio_bank_shift and + * &gpio_chip.of_gpio_bank_mask fields, and &gpio_chip.of_gpio_pin_shift and + * &gpio_chip.of_gpio_pin_mask are used to specify the encoding. + * + * Returns: + * The chip-relative index of the pin given by the GPIO specifier. + */ +int of_gpio_banked_xlate(struct gpio_chip *gc, + const struct of_phandle_args *gpiospec, u32 *flags) +{ + unsigned int offset = 0, bank, pin, i; + const u32 *spec = gpiospec->args; + + if (WARN_ON(gc->of_gpio_n_cells < 2)) + return -EINVAL; + + if (WARN_ON(gpiospec->args_count < gc->of_gpio_n_cells)) + return -EINVAL; + + bank = (spec[0] >> gc->of_gpio_bank_shift) & gc->of_gpio_bank_mask; + pin = (spec[0] >> gc->of_gpio_pin_shift) & gc->of_gpio_pin_mask; + + if (bank >= gc->num_banks) { + dev_err(gc->parent, "invalid bank number: %u\n", bank); + return -EINVAL; + } + + if (pin >= gc->banks[bank]->num_pins) { + dev_err(gc->parent, "invalid pin number: %u\n", pin); + return -EINVAL; + } + + for (i = 0; i < bank; i++) + offset += gc->banks[i]->num_pins; + + if (flags) + *flags = spec[1]; + + return offset + pin; +} +EXPORT_SYMBOL(of_gpio_banked_xlate); + +/** * of_mm_gpiochip_add_data - Add memory mapped GPIO chip (bank) * @np: device node of the GPIO chip * @mm_gc: pointer to the of_mm_gpio_chip allocated structure diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 7a16dd37bd3d..306c3a13e814 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1776,6 +1776,57 @@ static int gpiochip_add_irqchip(struct gpio_chip *gpiochip) gpiochip->to_irq = gpiochip_to_irq; gpiochip->irq.default_type = type; + if (gpiochip->num_banks > 0 && !gpiochip->irq.map) { + struct gpio_irq_chip *irq = &gpiochip->irq; + unsigned int i, j, offset = 0; + + if (!irq->parents) { + chip_err(gpiochip, "no parent interrupts defined\n"); + return -EINVAL; + } + + irq->map = devm_kcalloc(gpiochip->parent, gpiochip->ngpio, + sizeof(*irq->map), GFP_KERNEL); + if (!irq->map) + return -ENOMEM; + + for (i = 0; i < gpiochip->num_banks; i++) { + struct gpio_bank *bank = gpiochip->banks[i]; + unsigned int parent = bank->parent_irq; + + for (j = 0; j < bank->num_pins; j++) { + if (parent >= irq->num_parents) { + chip_err(gpiochip, + "invalid parent interrupt: %u\n", + parent); + return -EINVAL; + } + + irq->map[offset + j] = irq->parents[parent]; + } + + offset += bank->num_pins; + } + } + + if (gpiochip->num_banks > 0) { + unsigned int i; + + for (i = 0; i < gpiochip->num_banks; i++) { + struct gpio_bank *bank = gpiochip->banks[i]; + unsigned int num_pins = bank->num_pins; + + bank->pending = devm_kcalloc(gpiochip->parent, + BITS_TO_LONGS(num_pins), + sizeof(unsigned long), + GFP_KERNEL); + if (!bank->pending) + return -ENOMEM; + + bank->chip = gpiochip; + } + } + if (gpiochip->irq.domain_ops) ops = gpiochip->irq.domain_ops; else @@ -1984,6 +2035,53 @@ int gpiochip_irqchip_add_key(struct gpio_chip *gpiochip, } EXPORT_SYMBOL_GPL(gpiochip_irqchip_add_key); +/** + * gpio_irq_chip_banked_handler - interrupt handler for banked IRQ chips + * @desc: IRQ descriptor + * + * Drivers can use this interrupt handler for banked GPIO controllers. This + * implementation iterates over all banks and handles pending interrupts of + * the pins associated with the bank. + * + * This function uses driver specific parts, split out into the + * &gpio_chip.update_bank() callback, to retrieves the interrupt pending + * state for each of the GPIOs exposed by the given bank. + */ +void gpio_irq_chip_banked_handler(struct irq_desc *desc) +{ + struct gpio_chip *gpio = irq_desc_get_handler_data(desc); + struct irq_chip *irq = irq_desc_get_chip(desc); + unsigned int parent = irq_desc_get_irq(desc); + struct gpio_irq_chip *chip = &gpio->irq; + unsigned int i, offset = 0; + + chained_irq_enter(irq, desc); + + for (i = 0; i < gpio->num_banks; i++) { + struct gpio_bank *bank = gpio->banks[i]; + unsigned int pin, virq; + + if (parent != chip->parents[bank->parent_irq]) + goto skip; + + chip->update_bank(bank); + + for_each_set_bit(pin, bank->pending, bank->num_pins) { + virq = irq_find_mapping(chip->domain, offset + pin); + if (WARN_ON(virq == 0)) + continue; + + generic_handle_irq(virq); + } + +skip: + offset += bank->num_pins; + } + + chained_irq_exit(irq, desc); +} +EXPORT_SYMBOL_GPL(gpio_irq_chip_banked_handler); + #else /* CONFIG_GPIOLIB_IRQCHIP */ static inline int gpiochip_add_irqchip(struct gpio_chip *gpiochip) diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index c453e0716228..ecbeb50f8801 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h @@ -19,6 +19,47 @@ struct module; #ifdef CONFIG_GPIOLIB +/** + * struct gpio_bank - GPIO bank + * + * A GPIO bank, sometimes also referred to as port, represents a subset of the + * pins of a GPIO controller. The separation into banks is often caused by the + * sharing of one or more resource (register region, interrupt, ...) for each + * of the pins in the bank. + * + * In many cases the banking is transparent, but when it is not, GPIO drivers + * can use this code, along with some supporting fields in &struct gpio_chip. + */ +struct gpio_bank { + /** + * @chip: + * + * A pointer to the &struct gpio_chip that this bank belongs to. + */ + struct gpio_chip *chip; + + /** + * @parent_irq: + * + * The interrupt parent for this bank. + */ + unsigned int parent_irq; + + /** + * @num_pins: + * + * The number of pins provided by this bank. + */ + unsigned int num_pins; + + /** + * @pending: + * + * Current interrupt state of each pin in the bank. + */ + unsigned long *pending; +}; + #ifdef CONFIG_GPIOLIB_IRQCHIP /** * struct gpio_irq_chip - GPIO interrupt controller @@ -136,6 +177,15 @@ struct gpio_irq_chip { * in IRQ domain of the chip. */ unsigned long *valid_mask; + + /** + * @update_bank: + * + * Callback used by banked interrupt controllers. The driver updates + * the &gpio_bank.pending field of the given @bank with the current + * status for each of the GPIOs that it provides. + */ + void (*update_bank)(struct gpio_bank *bank); }; static inline struct gpio_irq_chip *to_gpio_irq_chip(struct irq_chip *chip) @@ -281,6 +331,24 @@ struct gpio_chip { struct gpio_irq_chip irq; #endif + /** + * @banks: + * + * If a GPIO controller is subdivided into multiple banks, the driver + * can use this field to store information about these banks. + * + * Note that the driver owns this field and the core will not modify + * it, only reference it. + */ + struct gpio_bank **banks; + + /** + * @num_banks: + * + * The number of banks described in @banks. + */ + unsigned int num_banks; + #if defined(CONFIG_OF_GPIO) /* * If CONFIG_OF is enabled, then all GPIO controllers described in the @@ -302,6 +370,38 @@ struct gpio_chip { unsigned int of_gpio_n_cells; /** + * @of_gpio_bank_shift: + * + * The offset of the field in the cell denoting the bank number of a + * specified GPIO. + */ + unsigned int of_gpio_bank_shift; + + /** + * @of_gpio_bank_mask: + * + * The mask of the field in the cell denoting the bank number of a + * specified GPIO. + */ + unsigned int of_gpio_bank_mask; + + /** + * @of_gpio_pin_shift: + * + * The offset of the field in the cell denoting the pin number of a + * specified GPIO within its bank. + */ + unsigned int of_gpio_pin_shift; + + /** + * @of_gpio_pin_mask: + * + * The mask of the field in the cell denoting the pin number of a + * specified GPIO within its bank. + */ + unsigned int of_gpio_pin_mask; + + /** * @of_xlate: * * Callback to translate a device tree GPIO specifier into a chip- @@ -374,6 +474,12 @@ int gpiochip_irq_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hwirq); void gpiochip_irq_unmap(struct irq_domain *d, unsigned int irq); +int gpio_banked_irq_domain_xlate(struct irq_domain *domain, + struct device_node *np, + const u32 *spec, unsigned int size, + unsigned long *hwirq, + unsigned int *type); + void gpiochip_set_chained_irqchip(struct gpio_chip *gpiochip, struct irq_chip *irqchip, unsigned int parent_irq, @@ -391,6 +497,8 @@ int gpiochip_irqchip_add_key(struct gpio_chip *gpiochip, bool nested, struct lock_class_key *lock_key); +void gpio_irq_chip_banked_handler(struct irq_desc *desc); + #ifdef CONFIG_LOCKDEP /* diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h index ca10f43564de..f85414dc31f4 100644 --- a/include/linux/of_gpio.h +++ b/include/linux/of_gpio.h @@ -66,6 +66,9 @@ extern void of_mm_gpiochip_remove(struct of_mm_gpio_chip *mm_gc); extern int of_gpio_simple_xlate(struct gpio_chip *gc, const struct of_phandle_args *gpiospec, u32 *flags); +extern int of_gpio_banked_xlate(struct gpio_chip *gc, + const struct of_phandle_args *gpiospec, + u32 *flags); #else /* CONFIG_OF_GPIO */ @@ -86,6 +89,13 @@ static inline int of_gpio_simple_xlate(struct gpio_chip *gc, return -ENOSYS; } +static inline int of_gpio_banked_xlate(struct gpio_chip *gc, + const struct of_phandle_args *gpiospec, + u32 *flags) +{ + return -ENOSYS; +} + #endif /* CONFIG_OF_GPIO */ /** From patchwork Fri Sep 1 18:57:35 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Reding X-Patchwork-Id: 808953 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="jshVj8d3"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3xkT6w1kRMz9sPm for ; Sat, 2 Sep 2017 04:59:04 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752329AbdIAS6c (ORCPT ); Fri, 1 Sep 2017 14:58:32 -0400 Received: from mail-wm0-f66.google.com ([74.125.82.66]:34847 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752569AbdIAS6H (ORCPT ); Fri, 1 Sep 2017 14:58:07 -0400 Received: by mail-wm0-f66.google.com with SMTP id e204so964328wma.2; Fri, 01 Sep 2017 11:58:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=YG7Ugx3dX0q5S01R7qpc3WHptGIboJ/nl2v2wFURo+0=; b=jshVj8d3o7a1g0gxwJGW/ctHKBG4lBdgLFA5hEToL/oitA4oUz2ec40Iz7nS0oYnq+ 1QqKMrDcFXAaWDMerOUtHmFcfvOYROoCuShvq6dKzVzcdq6ezOzXqX4x38jELUu6pWfl i8l8DXdttwmTGBZuxS8oUPLFhOET3Bd/OoiYCyRVtEGb5ZJwj8h5Rm/p3zl8EEAYCKdF Y1lIQTSeTdFBfweF6oUdfks4ifZdWITe30yXqs/IVl7wa2FQkwF+rdN2874QxyofiYfe nM17EByU5kFOedg23vcpgcJKVPtdHpovlEFaHviufjoBWI3m8HCtgbMVNNmBEDq3PUtc 5x3g== 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=YG7Ugx3dX0q5S01R7qpc3WHptGIboJ/nl2v2wFURo+0=; b=d2gbhgrBRh7gA9j/TV76sqV4C1H+90wOjQ1DEuuPatMDNFb71nSuDHZoGzhCCqKAKW TzaGx0dyIgZJTk6Y8PT/s9fzXv18KHg7AUNAu8UB7e57DB8ztjQOQfYSsOXIK4NUHd+D JOMOQAcPl2kKECgPrE+pt1JalmjnfbjsUbWS3obWvLEMB6QKLdFtKXn/LP54ABtGhJt6 vGxPrCMMyVm280yw/pVHYx3WtDq+SPMhA4hwCItZVXQpOzYoo83NOxYIBmUPpYWlmpXG 0vPfBm6F3Dd/ueGCkQTt2DwAo4sju6WzjzpfEvYtgiDMGLW7yuVZJSaJt0oAwloA9D44 wgXw== X-Gm-Message-State: AHPjjUiSVIicY09srBtuIP6k1fTWtezPMa2MNvp6xGG9PmFaYqhq0HZD VD4CjEjkLNYG8g== X-Google-Smtp-Source: ADKCNb7+p8kPzonGbrWSYUva0mvM/h8dG5NQT1nmKnL9KFwAfXd5/L70whJePAFIwKrlrpIg0M/hLA== X-Received: by 10.28.87.1 with SMTP id l1mr899216wmb.99.1504292285558; Fri, 01 Sep 2017 11:58:05 -0700 (PDT) Received: from localhost (p200300E41BD6D60076D02BFFFE273F51.dip0.t-ipconnect.de. [2003:e4:1bd6:d600:76d0:2bff:fe27:3f51]) by smtp.gmail.com with ESMTPSA id l4sm653323wrb.70.2017.09.01.11.58.04 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 01 Sep 2017 11:58:04 -0700 (PDT) From: Thierry Reding To: Linus Walleij Cc: Jonathan Hunter , linux-gpio@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 15/16] gpio: tegra: Use banked GPIO infrastructure Date: Fri, 1 Sep 2017 20:57:35 +0200 Message-Id: <20170901185736.28051-16-thierry.reding@gmail.com> X-Mailer: git-send-email 2.13.3 In-Reply-To: <20170901185736.28051-1-thierry.reding@gmail.com> References: <20170901185736.28051-1-thierry.reding@gmail.com> Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Thierry Reding Convert the Tegra GPIO driver to use the banked GPIO infrastructure, which simplifies some parts of the driver. Signed-off-by: Thierry Reding --- drivers/gpio/Kconfig | 1 + drivers/gpio/gpio-tegra.c | 203 ++++++++++++++++++++++------------------------ 2 files changed, 98 insertions(+), 106 deletions(-) diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index f9e22c6fdd02..9364f037fe86 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -439,6 +439,7 @@ config GPIO_TEGRA default ARCH_TEGRA depends on ARCH_TEGRA || COMPILE_TEST depends on OF_GPIO + select GPIOLIB_IRQCHIP help Say yes here to support GPIO pins on NVIDIA Tegra SoCs. diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c index fbaf974277df..250cebc3ab60 100644 --- a/drivers/gpio/gpio-tegra.c +++ b/drivers/gpio/gpio-tegra.c @@ -67,8 +67,8 @@ struct tegra_gpio_info; struct tegra_gpio_bank { - unsigned int bank; - unsigned int irq; + struct gpio_bank bank; + unsigned int index; spinlock_t lvl_lock[4]; spinlock_t dbc_lock[4]; /* Lock for updating debounce count register */ #ifdef CONFIG_PM_SLEEP @@ -84,6 +84,11 @@ struct tegra_gpio_bank { struct tegra_gpio_info *tgi; }; +static struct tegra_gpio_bank *to_tegra_gpio_bank(struct gpio_bank *bank) +{ + return container_of(bank, struct tegra_gpio_bank, bank); +} + struct tegra_gpio_soc_config { bool debounce_supported; u32 bank_stride; @@ -98,9 +103,14 @@ struct tegra_gpio_info { const struct tegra_gpio_soc_config *soc; struct gpio_chip gc; struct irq_chip ic; - u32 bank_count; }; +static inline struct tegra_gpio_info * +to_tegra_gpio_info(struct gpio_chip *chip) +{ + return container_of(chip, struct tegra_gpio_info, gc); +} + static inline void tegra_gpio_writel(struct tegra_gpio_info *tgi, u32 val, u32 reg) { @@ -264,8 +274,8 @@ static int tegra_gpio_to_irq(struct gpio_chip *chip, unsigned int offset) static void tegra_gpio_irq_ack(struct irq_data *d) { - struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d); - struct tegra_gpio_info *tgi = bank->tgi; + struct gpio_chip *chip = irq_data_get_irq_chip_data(d); + struct tegra_gpio_info *tgi = to_tegra_gpio_info(chip); unsigned int gpio = d->hwirq; tegra_gpio_writel(tgi, 1 << GPIO_BIT(gpio), GPIO_INT_CLR(tgi, gpio)); @@ -273,8 +283,8 @@ static void tegra_gpio_irq_ack(struct irq_data *d) static void tegra_gpio_irq_mask(struct irq_data *d) { - struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d); - struct tegra_gpio_info *tgi = bank->tgi; + struct gpio_chip *chip = irq_data_get_irq_chip_data(d); + struct tegra_gpio_info *tgi = to_tegra_gpio_info(chip); unsigned int gpio = d->hwirq; tegra_gpio_mask_write(tgi, GPIO_MSK_INT_ENB(tgi, gpio), gpio, 0); @@ -282,8 +292,8 @@ static void tegra_gpio_irq_mask(struct irq_data *d) static void tegra_gpio_irq_unmask(struct irq_data *d) { - struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d); - struct tegra_gpio_info *tgi = bank->tgi; + struct gpio_chip *chip = irq_data_get_irq_chip_data(d); + struct tegra_gpio_info *tgi = to_tegra_gpio_info(chip); unsigned int gpio = d->hwirq; tegra_gpio_mask_write(tgi, GPIO_MSK_INT_ENB(tgi, gpio), gpio, 1); @@ -292,12 +302,15 @@ static void tegra_gpio_irq_unmask(struct irq_data *d) static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type) { unsigned int gpio = d->hwirq, port = GPIO_PORT(gpio), lvl_type; - struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d); - struct tegra_gpio_info *tgi = bank->tgi; + struct gpio_chip *chip = irq_data_get_irq_chip_data(d); + struct tegra_gpio_info *tgi = to_tegra_gpio_info(chip); + struct tegra_gpio_bank *bank; unsigned long flags; u32 val; int ret; + bank = &tgi->bank_info[GPIO_BANK(gpio)]; + switch (type & IRQ_TYPE_SENSE_MASK) { case IRQ_TYPE_EDGE_RISING: lvl_type = GPIO_INT_LVL_EDGE_RISING; @@ -352,52 +365,27 @@ static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type) static void tegra_gpio_irq_shutdown(struct irq_data *d) { - struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d); - struct tegra_gpio_info *tgi = bank->tgi; - unsigned int gpio = d->hwirq; + struct gpio_chip *chip = irq_data_get_irq_chip_data(d); - gpiochip_unlock_as_irq(&tgi->gc, gpio); + gpiochip_unlock_as_irq(chip, d->hwirq); } -static void tegra_gpio_irq_handler(struct irq_desc *desc) +static void tegra_gpio_update_bank(struct gpio_bank *bank) { - unsigned int port, pin, gpio; - bool unmasked = false; - u32 lvl; - unsigned long sta; - struct irq_chip *chip = irq_desc_get_chip(desc); - struct tegra_gpio_bank *bank = irq_desc_get_handler_data(desc); - struct tegra_gpio_info *tgi = bank->tgi; - - chained_irq_enter(chip, desc); + struct tegra_gpio_info *tgi = to_tegra_gpio_info(bank->chip); + struct tegra_gpio_bank *b = to_tegra_gpio_bank(bank); + unsigned int port; for (port = 0; port < 4; port++) { - gpio = tegra_gpio_compose(bank->bank, port, 0); - sta = tegra_gpio_readl(tgi, GPIO_INT_STA(tgi, gpio)) & - tegra_gpio_readl(tgi, GPIO_INT_ENB(tgi, gpio)); - lvl = tegra_gpio_readl(tgi, GPIO_INT_LVL(tgi, gpio)); - - for_each_set_bit(pin, &sta, 8) { - tegra_gpio_writel(tgi, 1 << pin, - GPIO_INT_CLR(tgi, gpio)); - - /* if gpio is edge triggered, clear condition - * before executing the handler so that we don't - * miss edges - */ - if (!unmasked && lvl & (0x100 << pin)) { - unmasked = true; - chained_irq_exit(chip, desc); - } + unsigned int gpio = tegra_gpio_compose(b->index, port, 0); + u8 *pending = (u8 *)bank->pending; + u32 status, enable; - generic_handle_irq(irq_find_mapping(tgi->irq_domain, - gpio + pin)); - } - } - - if (!unmasked) - chained_irq_exit(chip, desc); + status = tegra_gpio_readl(tgi, GPIO_INT_STA(tgi, gpio)); + enable = tegra_gpio_readl(tgi, GPIO_INT_ENB(tgi, gpio)); + pending[port] = status & enable; + } } #ifdef CONFIG_PM_SLEEP @@ -410,7 +398,7 @@ static int tegra_gpio_resume(struct device *dev) local_irq_save(flags); - for (b = 0; b < tgi->bank_count; b++) { + for (b = 0; b < tgi->gc.num_banks; b++) { struct tegra_gpio_bank *bank = &tgi->bank_info[b]; for (p = 0; p < ARRAY_SIZE(bank->oe); p++) { @@ -449,7 +437,7 @@ static int tegra_gpio_suspend(struct device *dev) unsigned int b, p; local_irq_save(flags); - for (b = 0; b < tgi->bank_count; b++) { + for (b = 0; b < tgi->gc.num_banks; b++) { struct tegra_gpio_bank *bank = &tgi->bank_info[b]; for (p = 0; p < ARRAY_SIZE(bank->oe); p++) { @@ -484,20 +472,26 @@ static int tegra_gpio_suspend(struct device *dev) static int tegra_gpio_irq_set_wake(struct irq_data *d, unsigned int enable) { - struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d); - unsigned int gpio = d->hwirq; + struct gpio_chip *chip = irq_data_get_irq_chip_data(d); + unsigned int gpio = d->hwirq, parent_irq; + struct tegra_gpio_bank *b; + struct gpio_bank *bank; u32 port, bit, mask; + bank = chip->banks[GPIO_BANK(gpio)]; + b = to_tegra_gpio_bank(bank); port = GPIO_PORT(gpio); bit = GPIO_BIT(gpio); mask = BIT(bit); if (enable) - bank->wake_enb[port] |= mask; + b->wake_enb[port] |= mask; else - bank->wake_enb[port] &= ~mask; + b->wake_enb[port] &= ~mask; + + parent_irq = chip->irq.parents[bank->parent_irq]; - return irq_set_irq_wake(bank->irq, enable); + return irq_set_irq_wake(parent_irq, enable); } #endif @@ -511,7 +505,7 @@ static int dbg_gpio_show(struct seq_file *s, void *unused) struct tegra_gpio_info *tgi = s->private; unsigned int i, j; - for (i = 0; i < tgi->bank_count; i++) { + for (i = 0; i < tgi->gc.num_banks; i++) { for (j = 0; j < 4; j++) { unsigned int gpio = tegra_gpio_compose(i, j, 0); @@ -561,17 +555,18 @@ static const struct dev_pm_ops tegra_gpio_pm_ops = { }; /* - * This lock class tells lockdep that GPIO irqs are in a different category + * This lock class tells lockdep that GPIO IRQs are in a different category * than their parents, so it won't report false recursion. */ -static struct lock_class_key gpio_lock_class; +static struct lock_class_key tegra_gpio_lock_class; static int tegra_gpio_probe(struct platform_device *pdev) { struct tegra_gpio_info *tgi; struct resource *res; struct tegra_gpio_bank *bank; - unsigned int gpio, i, j; + struct gpio_irq_chip *irq; + unsigned int i, j; int ret; tgi = devm_kzalloc(&pdev->dev, sizeof(*tgi), GFP_KERNEL); @@ -580,14 +575,20 @@ static int tegra_gpio_probe(struct platform_device *pdev) tgi->soc = of_device_get_match_data(&pdev->dev); tgi->dev = &pdev->dev; + irq = &tgi->gc.irq; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + tgi->regs = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(tgi->regs)) + return PTR_ERR(tgi->regs); ret = platform_irq_count(pdev); if (ret < 0) return ret; - tgi->bank_count = ret; + tgi->gc.num_banks = ret; - if (!tgi->bank_count) { + if (!tgi->gc.num_banks) { dev_err(&pdev->dev, "Missing IRQ resource\n"); return -ENODEV; } @@ -602,7 +603,7 @@ static int tegra_gpio_probe(struct platform_device *pdev) tgi->gc.get_direction = tegra_gpio_get_direction; tgi->gc.to_irq = tegra_gpio_to_irq; tgi->gc.base = 0; - tgi->gc.ngpio = tgi->bank_count * 32; + tgi->gc.ngpio = tgi->gc.num_banks * 32; tgi->gc.parent = &pdev->dev; tgi->gc.of_node = pdev->dev.of_node; @@ -616,76 +617,66 @@ static int tegra_gpio_probe(struct platform_device *pdev) tgi->ic.irq_set_wake = tegra_gpio_irq_set_wake; #endif + irq = &tgi->gc.irq; + irq->chip = &tgi->ic; + irq->handler = handle_simple_irq; + irq->lock_key = &tegra_gpio_lock_class; + irq->default_type = IRQ_TYPE_NONE; + irq->parent_handler = gpio_irq_chip_banked_handler; + irq->update_bank = tegra_gpio_update_bank; + + irq->parents = devm_kcalloc(&pdev->dev, tgi->gc.num_banks, + sizeof(unsigned int), GFP_KERNEL); + if (!irq->parents) + return -ENOMEM; + + irq->num_parents = tgi->gc.num_banks; + platform_set_drvdata(pdev, tgi); if (tgi->soc->debounce_supported) tgi->gc.set_config = tegra_gpio_set_config; - tgi->bank_info = devm_kcalloc(&pdev->dev, tgi->bank_count, + tgi->bank_info = devm_kcalloc(&pdev->dev, tgi->gc.num_banks, sizeof(*tgi->bank_info), GFP_KERNEL); if (!tgi->bank_info) return -ENOMEM; - tgi->irq_domain = irq_domain_add_linear(pdev->dev.of_node, - tgi->gc.ngpio, - &irq_domain_simple_ops, NULL); - if (!tgi->irq_domain) - return -ENODEV; + tgi->gc.banks = devm_kcalloc(&pdev->dev, tgi->gc.num_banks, + sizeof(struct gpio_bank *), + GFP_KERNEL); + if (!tgi->gc.banks) + return -ENOMEM; - for (i = 0; i < tgi->bank_count; i++) { + for (i = 0; i < tgi->gc.num_banks; i++) { ret = platform_get_irq(pdev, i); if (ret < 0) { dev_err(&pdev->dev, "Missing IRQ resource: %d\n", ret); return ret; } + irq->parents[i] = ret; + bank = &tgi->bank_info[i]; - bank->bank = i; - bank->irq = ret; - bank->tgi = tgi; - } + bank->bank.chip = &tgi->gc; + bank->bank.parent_irq = i; + bank->bank.num_pins = 32; + bank->index = i; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - tgi->regs = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(tgi->regs)) - return PTR_ERR(tgi->regs); + tgi->gc.banks[i] = &bank->bank; - for (i = 0; i < tgi->bank_count; i++) { for (j = 0; j < 4; j++) { - int gpio = tegra_gpio_compose(i, j, 0); + unsigned int gpio = tegra_gpio_compose(i, j, 0); tegra_gpio_writel(tgi, 0x00, GPIO_INT_ENB(tgi, gpio)); + spin_lock_init(&bank->lvl_lock[j]); + spin_lock_init(&bank->dbc_lock[j]); } } ret = devm_gpiochip_add_data(&pdev->dev, &tgi->gc, tgi); - if (ret < 0) { - irq_domain_remove(tgi->irq_domain); + if (ret < 0) return ret; - } - - for (gpio = 0; gpio < tgi->gc.ngpio; gpio++) { - int irq = irq_create_mapping(tgi->irq_domain, gpio); - /* No validity check; all Tegra GPIOs are valid IRQs */ - - bank = &tgi->bank_info[GPIO_BANK(gpio)]; - - irq_set_lockdep_class(irq, &gpio_lock_class); - irq_set_chip_data(irq, bank); - irq_set_chip_and_handler(irq, &tgi->ic, handle_simple_irq); - } - - for (i = 0; i < tgi->bank_count; i++) { - bank = &tgi->bank_info[i]; - - irq_set_chained_handler_and_data(bank->irq, - tegra_gpio_irq_handler, bank); - - for (j = 0; j < 4; j++) { - spin_lock_init(&bank->lvl_lock[j]); - spin_lock_init(&bank->dbc_lock[j]); - } - } tegra_gpio_debuginit(tgi); From patchwork Fri Sep 1 18:57:36 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Reding X-Patchwork-Id: 808951 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-gpio-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="TB9yO/C1"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3xkT685B2Jz9sQl for ; Sat, 2 Sep 2017 04:58:24 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752601AbdIAS6M (ORCPT ); Fri, 1 Sep 2017 14:58:12 -0400 Received: from mail-wm0-f68.google.com ([74.125.82.68]:34363 "EHLO mail-wm0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752588AbdIAS6J (ORCPT ); Fri, 1 Sep 2017 14:58:09 -0400 Received: by mail-wm0-f68.google.com with SMTP id l19so970036wmi.1; Fri, 01 Sep 2017 11:58:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=6HdMk8gqbdAzOBlpD1yg++ZCy9OJVxKiPShQ/RGw4ls=; b=TB9yO/C1kEPfKp9SBMqr6iiKd60Z1dcTVS1Cnt8aI5fvHjrcoHIrHuXwbKDUGLdPlu EjElXb3Ymc0eCY7wpub8TYWaM0KwGo1Eublr1T/7zvJ6RpLEYz8P7Bq9F0R4MMZWmMN/ pzvY3flXWEeg0nh5a+PthLL8u9r+q3FTTiMl5SfvGHE6SyQUBy8uLq0jcWJN98dxnQqo a6Pd9d1ifY2NlQa3SoAVIK+xLH0YsYHDUaIfWSeJwr6EI63t+C21Lzr7QM20gwSMBerX BJpaKx9IC+tcXvaw6VXJasv2QxQuJdZmvjO/ZCzBz4pzXWJ3Kf6encjqvDIIaqrZeVvz 0ujw== 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=6HdMk8gqbdAzOBlpD1yg++ZCy9OJVxKiPShQ/RGw4ls=; b=isaIg4Kq1BoXmZI/dhUVgrOuRbsjeIoT4SCJMXYRCu6LvUVJUH7y7Y2SOTV961fyUE A3AxkqDn5SchiKYlnKPdG79ZwfOk9aDyZ37rm/rTzXBlbRp+I9oqlFGh3J//zkVrqEda nBlAZTqJxZRZVKTc43wjuExArxtXvHK+cbEaUznP2S5ED2Uust5jRdMOTqHsYer95TY6 ihOmPb5kXp4a4qZJxUlD9L3v+XitHdE2L+gzBu+yMbnVAFiRlDV/YCsc25Vm9STvuwzr VSCC2+vHaiGhpOX7DS6PL3zFlQMu5J7fEkPHtBRdvAIryYsv876VHykNWs5GmOBdKah0 4NxQ== X-Gm-Message-State: AHPjjUhvStWglBzlDeMvePP9R2yqthIiHH94ANYScOyfJx0jv9eRIuhw h1X/Xpjm0f/dUKPk X-Google-Smtp-Source: ADKCNb7YWqrNTfCehhZkazmGAtpxI6NBAUbr/pTfrRadzzUzYqzynnHRn3V2rnN9uuoUmY6xXoq5sw== X-Received: by 10.28.1.86 with SMTP id 83mr1176667wmb.191.1504292287295; Fri, 01 Sep 2017 11:58:07 -0700 (PDT) Received: from localhost (p200300E41BD6D60076D02BFFFE273F51.dip0.t-ipconnect.de. [2003:e4:1bd6:d600:76d0:2bff:fe27:3f51]) by smtp.gmail.com with ESMTPSA id o191sm334549wmd.35.2017.09.01.11.58.06 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 01 Sep 2017 11:58:06 -0700 (PDT) From: Thierry Reding To: Linus Walleij Cc: Jonathan Hunter , linux-gpio@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 16/16] gpio: tegra186: Use banked GPIO infrastructure Date: Fri, 1 Sep 2017 20:57:36 +0200 Message-Id: <20170901185736.28051-17-thierry.reding@gmail.com> X-Mailer: git-send-email 2.13.3 In-Reply-To: <20170901185736.28051-1-thierry.reding@gmail.com> References: <20170901185736.28051-1-thierry.reding@gmail.com> Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org From: Thierry Reding Convert the Tegra186 GPIO driver to use the banked GPIO infrastructure, which simplifies some parts of the driver. Signed-off-by: Thierry Reding --- drivers/gpio/gpio-tegra186.c | 211 ++++++++++++++++--------------------------- 1 file changed, 79 insertions(+), 132 deletions(-) diff --git a/drivers/gpio/gpio-tegra186.c b/drivers/gpio/gpio-tegra186.c index 162dc6b41ae8..4926b98a05f6 100644 --- a/drivers/gpio/gpio-tegra186.c +++ b/drivers/gpio/gpio-tegra186.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -44,15 +45,27 @@ #define TEGRA186_GPIO_INTERRUPT_STATUS(x) (0x100 + (x) * 4) -struct tegra_gpio_port { +struct tegra_gpio_port_soc { const char *name; unsigned int offset; unsigned int pins; unsigned int irq; }; +struct tegra_gpio_port { + struct gpio_bank bank; + unsigned int offset; + const char *name; +}; + +static inline struct tegra_gpio_port * +to_tegra_gpio_port(struct gpio_bank *bank) +{ + return container_of(bank, struct tegra_gpio_port, bank); +} + struct tegra_gpio_soc { - const struct tegra_gpio_port *ports; + const struct tegra_gpio_port_soc *ports; unsigned int num_ports; const char *name; }; @@ -60,21 +73,21 @@ struct tegra_gpio_soc { struct tegra_gpio { struct gpio_chip gpio; struct irq_chip intc; - unsigned int num_irq; - unsigned int *irq; const struct tegra_gpio_soc *soc; + struct tegra_gpio_port *ports; + void __iomem *base; }; -static const struct tegra_gpio_port * +static const struct tegra_gpio_port_soc * tegra186_gpio_get_port(struct tegra_gpio *gpio, unsigned int *pin) { unsigned int start = 0, i; for (i = 0; i < gpio->soc->num_ports; i++) { - const struct tegra_gpio_port *port = &gpio->soc->ports[i]; + const struct tegra_gpio_port_soc *port = &gpio->soc->ports[i]; if (*pin >= start && *pin < start + port->pins) { *pin -= start; @@ -90,7 +103,7 @@ tegra186_gpio_get_port(struct tegra_gpio *gpio, unsigned int *pin) static void __iomem *tegra186_gpio_get_base(struct tegra_gpio *gpio, unsigned int pin) { - const struct tegra_gpio_port *port; + const struct tegra_gpio_port_soc *port; port = tegra186_gpio_get_port(gpio, &pin); if (!port) @@ -206,39 +219,10 @@ static void tegra186_gpio_set(struct gpio_chip *chip, unsigned int offset, writel(value, base + TEGRA186_GPIO_OUTPUT_VALUE); } -static int tegra186_gpio_of_xlate(struct gpio_chip *chip, - const struct of_phandle_args *spec, - u32 *flags) -{ - struct tegra_gpio *gpio = gpiochip_get_data(chip); - unsigned int port, pin, i, offset = 0; - - if (WARN_ON(chip->of_gpio_n_cells < 2)) - return -EINVAL; - - if (WARN_ON(spec->args_count < chip->of_gpio_n_cells)) - return -EINVAL; - - port = spec->args[0] / 8; - pin = spec->args[0] % 8; - - if (port >= gpio->soc->num_ports) { - dev_err(chip->parent, "invalid port number: %u\n", port); - return -EINVAL; - } - - for (i = 0; i < port; i++) - offset += gpio->soc->ports[i].pins; - - if (flags) - *flags = spec->args[1]; - - return offset + pin; -} - static void tegra186_irq_ack(struct irq_data *data) { - struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data); + struct gpio_chip *chip = irq_data_get_irq_chip_data(data); + struct tegra_gpio *gpio = gpiochip_get_data(chip); void __iomem *base; base = tegra186_gpio_get_base(gpio, data->hwirq); @@ -250,7 +234,8 @@ static void tegra186_irq_ack(struct irq_data *data) static void tegra186_irq_mask(struct irq_data *data) { - struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data); + struct gpio_chip *chip = irq_data_get_irq_chip_data(data); + struct tegra_gpio *gpio = gpiochip_get_data(chip); void __iomem *base; u32 value; @@ -265,7 +250,8 @@ static void tegra186_irq_mask(struct irq_data *data) static void tegra186_irq_unmask(struct irq_data *data) { - struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data); + struct gpio_chip *chip = irq_data_get_irq_chip_data(data); + struct tegra_gpio *gpio = gpiochip_get_data(chip); void __iomem *base; u32 value; @@ -280,7 +266,8 @@ static void tegra186_irq_unmask(struct irq_data *data) static int tegra186_irq_set_type(struct irq_data *data, unsigned int flow) { - struct tegra_gpio *gpio = irq_data_get_irq_chip_data(data); + struct gpio_chip *chip = irq_data_get_irq_chip_data(data); + struct tegra_gpio *gpio = gpiochip_get_data(chip); void __iomem *base; u32 value; @@ -332,76 +319,22 @@ static int tegra186_irq_set_type(struct irq_data *data, unsigned int flow) return 0; } -static void tegra186_gpio_irq(struct irq_desc *desc) -{ - struct tegra_gpio *gpio = irq_desc_get_handler_data(desc); - struct irq_domain *domain = gpio->gpio.irq.domain; - struct irq_chip *chip = irq_desc_get_chip(desc); - unsigned int parent = irq_desc_get_irq(desc); - unsigned int i, offset = 0; - - chained_irq_enter(chip, desc); - - for (i = 0; i < gpio->soc->num_ports; i++) { - const struct tegra_gpio_port *port = &gpio->soc->ports[i]; - void __iomem *base = gpio->base + port->offset; - unsigned int pin, irq; - unsigned long value; - - /* skip ports that are not associated with this controller */ - if (parent != gpio->irq[port->irq]) - goto skip; - - value = readl(base + TEGRA186_GPIO_INTERRUPT_STATUS(1)); - - for_each_set_bit(pin, &value, port->pins) { - irq = irq_find_mapping(domain, offset + pin); - if (WARN_ON(irq == 0)) - continue; - - generic_handle_irq(irq); - } - -skip: - offset += port->pins; - } - - chained_irq_exit(chip, desc); -} - -static int tegra186_gpio_irq_domain_xlate(struct irq_domain *domain, - struct device_node *np, - const u32 *spec, unsigned int size, - unsigned long *hwirq, - unsigned int *type) +static void tegra186_gpio_update_bank(struct gpio_bank *bank) { - struct tegra_gpio *gpio = gpiochip_get_data(domain->host_data); - unsigned int port, pin, i, offset = 0; - - if (size < 2) - return -EINVAL; - - port = spec[0] / 8; - pin = spec[0] % 8; - - if (port >= gpio->soc->num_ports) { - dev_err(gpio->gpio.parent, "invalid port number: %u\n", port); - return -EINVAL; - } - - for (i = 0; i < port; i++) - offset += gpio->soc->ports[i].pins; + struct tegra_gpio_port *port = to_tegra_gpio_port(bank); + struct tegra_gpio *gpio = gpiochip_get_data(bank->chip); + void __iomem *base = gpio->base + port->offset; + u32 value; - *type = spec[1] & IRQ_TYPE_SENSE_MASK; - *hwirq = offset + pin; + value = readl(base + TEGRA186_GPIO_INTERRUPT_STATUS(1)); - return 0; + bank->pending[0] = value; } static const struct irq_domain_ops tegra186_gpio_irq_domain_ops = { .map = gpiochip_irq_map, .unmap = gpiochip_irq_unmap, - .xlate = tegra186_gpio_irq_domain_xlate, + .xlate = gpio_banked_irq_domain_xlate, }; static struct lock_class_key tegra186_gpio_lock_class; @@ -420,6 +353,7 @@ static int tegra186_gpio_probe(struct platform_device *pdev) return -ENOMEM; gpio->soc = of_device_get_match_data(&pdev->dev); + irq = &gpio->gpio.irq; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gpio"); gpio->base = devm_ioremap_resource(&pdev->dev, res); @@ -430,21 +364,47 @@ static int tegra186_gpio_probe(struct platform_device *pdev) if (err < 0) return err; - gpio->num_irq = err; + irq->num_parents = err; - gpio->irq = devm_kcalloc(&pdev->dev, gpio->num_irq, sizeof(*gpio->irq), - GFP_KERNEL); - if (!gpio->irq) + irq->parents = devm_kcalloc(&pdev->dev, irq->num_parents, + sizeof(*irq->parents), GFP_KERNEL); + if (!irq->parents) return -ENOMEM; - for (i = 0; i < gpio->num_irq; i++) { + for (i = 0; i < irq->num_parents; i++) { err = platform_get_irq(pdev, i); if (err < 0) return err; - gpio->irq[i] = err; + irq->parents[i] = err; } + gpio->ports = devm_kcalloc(&pdev->dev, gpio->soc->num_ports, + sizeof(struct tegra_gpio_port), + GFP_KERNEL); + if (!gpio->ports) + return -ENOMEM; + + gpio->gpio.banks = devm_kcalloc(&pdev->dev, gpio->soc->num_ports, + sizeof(struct gpio_bank *), + GFP_KERNEL); + if (!gpio->gpio.banks) + return -ENOMEM; + + for (i = 0; i < gpio->soc->num_ports; i++) { + const struct tegra_gpio_port_soc *soc = &gpio->soc->ports[i]; + struct tegra_gpio_port *port = &gpio->ports[i]; + + gpio->gpio.banks[i] = &port->bank; + port->bank.parent_irq = soc->irq; + port->bank.num_pins = soc->pins; + + port->offset = soc->offset; + port->name = soc->name; + } + + gpio->gpio.num_banks = gpio->soc->num_ports; + gpio->gpio.label = gpio->soc->name; gpio->gpio.parent = &pdev->dev; @@ -465,7 +425,7 @@ static int tegra186_gpio_probe(struct platform_device *pdev) return -ENOMEM; for (i = 0, offset = 0; i < gpio->soc->num_ports; i++) { - const struct tegra_gpio_port *port = &gpio->soc->ports[i]; + const struct tegra_gpio_port_soc *port = &gpio->soc->ports[i]; char *name; for (j = 0; j < port->pins; j++) { @@ -484,7 +444,11 @@ static int tegra186_gpio_probe(struct platform_device *pdev) gpio->gpio.of_node = pdev->dev.of_node; gpio->gpio.of_gpio_n_cells = 2; - gpio->gpio.of_xlate = tegra186_gpio_of_xlate; + gpio->gpio.of_gpio_bank_shift = 3; + gpio->gpio.of_gpio_bank_mask = 0x1fffffff; + gpio->gpio.of_gpio_pin_shift = 0; + gpio->gpio.of_gpio_pin_mask = 0x7; + gpio->gpio.of_xlate = of_gpio_banked_xlate; gpio->intc.name = pdev->dev.of_node->name; gpio->intc.irq_ack = tegra186_irq_ack; @@ -492,31 +456,14 @@ static int tegra186_gpio_probe(struct platform_device *pdev) gpio->intc.irq_unmask = tegra186_irq_unmask; gpio->intc.irq_set_type = tegra186_irq_set_type; - irq = &gpio->gpio.irq; irq->chip = &gpio->intc; irq->first = 0; irq->domain_ops = &tegra186_gpio_irq_domain_ops; irq->handler = handle_simple_irq; irq->lock_key = &tegra186_gpio_lock_class; irq->default_type = IRQ_TYPE_NONE; - irq->parent_handler = tegra186_gpio_irq; - irq->parent_handler_data = gpio; - irq->num_parents = gpio->num_irq; - irq->parents = gpio->irq; - - irq->map = devm_kcalloc(&pdev->dev, gpio->gpio.ngpio, - sizeof(*irq->map), GFP_KERNEL); - if (!irq->map) - return -ENOMEM; - - for (i = 0, offset = 0; i < gpio->soc->num_ports; i++) { - const struct tegra_gpio_port *port = &gpio->soc->ports[i]; - - for (j = 0; j < port->pins; j++) - irq->map[offset + j] = irq->parents[port->irq]; - - offset += port->pins; - } + irq->parent_handler = gpio_irq_chip_banked_handler; + irq->update_bank = tegra186_gpio_update_bank; platform_set_drvdata(pdev, gpio); @@ -540,7 +487,7 @@ static int tegra186_gpio_remove(struct platform_device *pdev) .irq = controller, \ } -static const struct tegra_gpio_port tegra186_main_ports[] = { +static const struct tegra_gpio_port_soc tegra186_main_ports[] = { TEGRA_MAIN_GPIO_PORT( A, 0x2000, 7, 2), TEGRA_MAIN_GPIO_PORT( B, 0x3000, 7, 3), TEGRA_MAIN_GPIO_PORT( C, 0x3200, 7, 3), @@ -580,7 +527,7 @@ static const struct tegra_gpio_soc tegra186_main_soc = { .irq = controller, \ } -static const struct tegra_gpio_port tegra186_aon_ports[] = { +static const struct tegra_gpio_port_soc tegra186_aon_ports[] = { TEGRA_AON_GPIO_PORT( S, 0x0200, 5, 0), TEGRA_AON_GPIO_PORT( U, 0x0400, 6, 0), TEGRA_AON_GPIO_PORT( V, 0x0800, 8, 0),