From mboxrd@z Thu Jan 1 00:00:00 1970 From: Alexandre Courbot Subject: [PATCH 8/9] gpiolib: use gpio_chips list in gpio_to_desc Date: Sun, 3 Feb 2013 01:29:31 +0900 Message-ID: <1359822572-26009-10-git-send-email-acourbot@nvidia.com> References: <1359822572-26009-1-git-send-email-acourbot@nvidia.com> Return-path: Received: from mail-da0-f50.google.com ([209.85.210.50]:47651 "EHLO mail-da0-f50.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758066Ab3BBQ1l (ORCPT ); Sat, 2 Feb 2013 11:27:41 -0500 In-Reply-To: <1359822572-26009-1-git-send-email-acourbot@nvidia.com> Sender: linux-arch-owner@vger.kernel.org List-ID: To: Grant Likely , Linus Walleij , Arnd Bergmann Cc: linux-arch@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, gnurou@gmail.com, Alexandre Courbot Parse the list of chips to find the descriptor corresponding to a GPIO number instead of directly picking the entry of the global gpio_desc[] array, which is due to be removed. This turns the complexity of converting a GPIO number into a descriptor from O(1) to O(n) where n is the number of GPIO chips in the system. Since n is ought to be small anyway, there should be no noticeable performance impact. Moreover, GPIO users who care for speed already have implemented their own gpio_get_value() and gpio_set_value() with a fast path for the GPIO numbers that matter and this change does not affect such use cases. The descriptor-based GPIO API, due to be introduced soon, will make this lookup unnecessary. Signed-off-by: Alexandre Courbot --- drivers/gpio/gpiolib.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 9599b9a..0247c48 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -122,10 +122,21 @@ static int gpio_chip_hwgpio(const struct gpio_desc *desc) */ static struct gpio_desc *gpio_to_desc(unsigned gpio) { - if (WARN(!gpio_is_valid(gpio), "invalid GPIO %d\n", gpio)) - return NULL; - else - return &gpio_desc[gpio]; + struct gpio_chip *chip; + + list_for_each_entry(chip, &gpio_chips, list) { + int gpio_min = chip->base; + int gpio_max = gpio_min + chip->ngpio; + if (gpio >= gpio_min && gpio < gpio_max) + return &chip->desc[gpio - gpio_min]; + else if (gpio < gpio_min) + /* gpio_chips are ordered by base, so we won't get any + * hit if we arrive here... */ + break; + } + + pr_warn("%s: no registered chip to handle GPIO %d\n", __func__, gpio); + return NULL; } /** -- 1.8.1.1