Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757487Ab1CAX3M (ORCPT ); Tue, 1 Mar 2011 18:29:12 -0500 Received: from xes-mad.com ([216.165.139.218]:22685 "EHLO xes-mad.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756456Ab1CAX3K (ORCPT ); Tue, 1 Mar 2011 18:29:10 -0500 From: Peter Tyser To: linux-kernel@vger.kernel.org Cc: Peter Tyser , Alek Du , Samuel Ortiz , David Brownell , Eric Miao , =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= , Mark Brown , Joe Perches , Alan Cox , Grant Likely Subject: [PATCH v5 2/4] gpiolib: Add ability to get GPIO direction Date: Tue, 1 Mar 2011 17:28:18 -0600 Message-Id: <1299022100-14564-2-git-send-email-ptyser@xes-inc.com> X-Mailer: git-send-email 1.7.0.4 In-Reply-To: <1299022100-14564-1-git-send-email-ptyser@xes-inc.com> References: <1299022100-14564-1-git-send-email-ptyser@xes-inc.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3904 Lines: 112 Add a new get_direction() function to the gpio_chip structure. This is useful so that the direction of a GPIO can be determined when its initially exported. Previously, the direction defaulted to "unknown" regardless of the actual configuration of the GPIO. If a GPIO driver implements get_direction(), it is called in gpio_request() to set the initial direction of the GPIO accurately. Cc: Alek Du Cc: Samuel Ortiz Cc: David Brownell Cc: Eric Miao Cc: Uwe Kleine-König Cc: Mark Brown Cc: Joe Perches Cc: Alan Cox Cc: Grant Likely Signed-off-by: Peter Tyser --- Changes since v1: - Add support for "unknown" direction Changes since v2: Based on Wolfram's feedback: - Use GPIOF_DIR_* flags as returns from get_direction() - Call spin_lock_irqsave() to before setting flags Changes since v3: - Removed "pin" references from the commit message - Added might_sleep() call - Made the direction always be set in gpio_request() Change since V4: - None drivers/gpio/gpiolib.c | 25 +++++++++++++++++++++++++ include/asm-generic/gpio.h | 4 ++++ 2 files changed, 29 insertions(+), 0 deletions(-) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index eb74311..106164f 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -1174,6 +1174,7 @@ int gpio_request(unsigned gpio, const char *label) struct gpio_desc *desc; struct gpio_chip *chip; int status = -EINVAL; + int dir = -1; /* Default to unknown direction */ unsigned long flags; spin_lock_irqsave(&gpio_lock, flags); @@ -1214,6 +1215,30 @@ int gpio_request(unsigned gpio, const char *label) } } + if (chip->get_direction) { + /* chip->get_direction may sleep */ + spin_unlock_irqrestore(&gpio_lock, flags); + might_sleep_if(chip->can_sleep); + dir = chip->get_direction(chip, gpio - chip->base); + spin_lock_irqsave(&gpio_lock, flags); + } + + switch (dir) { + case GPIOF_DIR_OUT: + set_bit(FLAG_DIR_OUT, &desc->flags); + clear_bit(FLAG_DIR_IN, &desc->flags); + break; + case GPIOF_DIR_IN: + set_bit(FLAG_DIR_IN, &desc->flags); + clear_bit(FLAG_DIR_OUT, &desc->flags); + break; + default: + /* Direction isn't known */ + clear_bit(FLAG_DIR_OUT, &desc->flags); + clear_bit(FLAG_DIR_IN, &desc->flags); + break; + } + done: if (status) pr_debug("gpio_request: gpio-%d (%s) status %d\n", diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h index ff5c660..6af5a3e 100644 --- a/include/asm-generic/gpio.h +++ b/include/asm-generic/gpio.h @@ -57,6 +57,8 @@ struct device_node; * @direction_input: configures signal "offset" as input, or returns error * @get: returns value for signal "offset"; for output signals this * returns either the value actually sensed, or zero + * @get_direction: optional hook to determine if a GPIO signal is configured + * as an input, output, or unknown * @direction_output: configures signal "offset" as output, or returns error * @set: assigns output value for signal "offset" * @to_irq: optional hook supporting non-static gpio_to_irq() mappings; @@ -101,6 +103,8 @@ struct gpio_chip { unsigned offset); int (*get)(struct gpio_chip *chip, unsigned offset); + int (*get_direction)(struct gpio_chip *chip, + unsigned offset); int (*direction_output)(struct gpio_chip *chip, unsigned offset, int value); int (*set_debounce)(struct gpio_chip *chip, -- 1.7.0.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/