From patchwork Mon Aug 10 11:44:51 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Roger Quadros X-Patchwork-Id: 40394 X-Patchwork-Delegate: tony@atomide.com Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id n7ABjNGr004024 for ; Mon, 10 Aug 2009 11:45:24 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753070AbZHJLpU (ORCPT ); Mon, 10 Aug 2009 07:45:20 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753270AbZHJLpU (ORCPT ); Mon, 10 Aug 2009 07:45:20 -0400 Received: from smtp.nokia.com ([192.100.105.134]:39740 "EHLO mgw-mx09.nokia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753070AbZHJLpU (ORCPT ); Mon, 10 Aug 2009 07:45:20 -0400 Received: from vaebh106.NOE.Nokia.com (vaebh106.europe.nokia.com [10.160.244.32]) by mgw-mx09.nokia.com (Switch-3.3.3/Switch-3.3.3) with ESMTP id n7ABijSE024734; Mon, 10 Aug 2009 06:44:59 -0500 Received: from vaebh104.NOE.Nokia.com ([10.160.244.30]) by vaebh106.NOE.Nokia.com with Microsoft SMTPSVC(6.0.3790.3959); Mon, 10 Aug 2009 14:45:10 +0300 Received: from mgw-sa01.ext.nokia.com ([147.243.1.47]) by vaebh104.NOE.Nokia.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.3959); Mon, 10 Aug 2009 14:45:09 +0300 Received: from localhost.localdomain (esdhcp038133.research.nokia.com [172.21.38.133]) by mgw-sa01.ext.nokia.com (Switch-3.3.3/Switch-3.3.3) with ESMTP id n7ABj6OP030876; Mon, 10 Aug 2009 14:45:06 +0300 From: Roger Quadros To: tony@atomide.com Cc: linux-omap@vger.kernel.org Subject: [PATCH v3] OMAP: GPIO: Fix incorrect gpio_get logic for output GPIOs Date: Mon, 10 Aug 2009 14:44:51 +0300 Message-Id: <1249904691-4810-1-git-send-email-ext-roger.quadros@nokia.com> X-Mailer: git-send-email 1.6.0.4 X-OriginalArrivalTime: 10 Aug 2009 11:45:09.0779 (UTC) FILETIME=[0389EE30:01CA19B0] X-Nokia-AV: Clean Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org gpio_get() should return DATAIN register value when the GPIO is configured as input whereas it should return DATAOUT register value when the GPIO is configured as output. Now /sys/kernel/debug/gpio shows proper values for output GPIOs Signed-off-by: Roger Quadros --- arch/arm/plat-omap/gpio.c | 121 +++++++++++++++++++++++++++++++++------------ 1 files changed, 89 insertions(+), 32 deletions(-) diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c index 26b387c..9c16ca8 100644 --- a/arch/arm/plat-omap/gpio.c +++ b/arch/arm/plat-omap/gpio.c @@ -476,14 +476,12 @@ static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable) __raw_writel(l, reg); } -static int __omap_get_gpio_datain(int gpio) +static int _get_gpio_datain(struct gpio_bank *bank, int gpio) { - struct gpio_bank *bank; void __iomem *reg; if (check_gpio(gpio) < 0) return -EINVAL; - bank = get_gpio_bank(gpio); reg = bank->base; switch (bank->method) { #ifdef CONFIG_ARCH_OMAP1 @@ -524,6 +522,53 @@ static int __omap_get_gpio_datain(int gpio) & (1 << get_gpio_index(gpio))) != 0; } +static int _get_gpio_dataout(struct gpio_bank *bank, int gpio) +{ + void __iomem *reg; + + if (check_gpio(gpio) < 0) + return -EINVAL; + reg = bank->base; + + switch (bank->method) { +#ifdef CONFIG_ARCH_OMAP1 + case METHOD_MPUIO: + reg += OMAP_MPUIO_OUTPUT; + break; +#endif +#ifdef CONFIG_ARCH_OMAP15XX + case METHOD_GPIO_1510: + reg += OMAP1510_GPIO_DATA_OUTPUT; + break; +#endif +#ifdef CONFIG_ARCH_OMAP16XX + case METHOD_GPIO_1610: + reg += OMAP1610_GPIO_DATAOUT; + break; +#endif +#ifdef CONFIG_ARCH_OMAP730 + case METHOD_GPIO_730: + reg += OMAP730_GPIO_DATA_OUTPUT; + break; +#endif +#ifdef CONFIG_ARCH_OMAP850 + case METHOD_GPIO_850: + reg += OMAP850_GPIO_DATA_OUTPUT; + break; +#endif +#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) || \ + defined(CONFIG_ARCH_OMAP4) + case METHOD_GPIO_24XX: + reg += OMAP24XX_GPIO_DATAOUT; + break; +#endif + default: + return -EINVAL; + } + + return (__raw_readl(reg) & (1 << get_gpio_index(gpio))) != 0; +} + #define MOD_REG_BIT(reg, bit_mask, set) \ do { \ int l = __raw_readl(base + reg); \ @@ -1350,9 +1395,49 @@ static int gpio_input(struct gpio_chip *chip, unsigned offset) return 0; } +static int gpio_is_input(struct gpio_bank *bank, int mask) +{ + void __iomem *reg = bank->base; + + switch (bank->method) { + case METHOD_MPUIO: + reg += OMAP_MPUIO_IO_CNTL; + break; + case METHOD_GPIO_1510: + reg += OMAP1510_GPIO_DIR_CONTROL; + break; + case METHOD_GPIO_1610: + reg += OMAP1610_GPIO_DIRECTION; + break; + case METHOD_GPIO_730: + reg += OMAP730_GPIO_DIR_CONTROL; + break; + case METHOD_GPIO_850: + reg += OMAP850_GPIO_DIR_CONTROL; + break; + case METHOD_GPIO_24XX: + reg += OMAP24XX_GPIO_OE; + break; + } + return __raw_readl(reg) & mask; +} + static int gpio_get(struct gpio_chip *chip, unsigned offset) { - return __omap_get_gpio_datain(chip->base + offset); + struct gpio_bank *bank; + void __iomem *reg; + int gpio; + u32 mask; + + gpio = chip->base + offset; + bank = get_gpio_bank(gpio); + reg = bank->base; + mask = 1 << get_gpio_index(gpio); + + if (gpio_is_input(bank, mask)) + return _get_gpio_datain(bank, gpio); + else + return _get_gpio_dataout(bank, gpio); } static int gpio_output(struct gpio_chip *chip, unsigned offset, int value) @@ -1886,34 +1971,6 @@ arch_initcall(omap_gpio_sysinit); #include #include -static int gpio_is_input(struct gpio_bank *bank, int mask) -{ - void __iomem *reg = bank->base; - - switch (bank->method) { - case METHOD_MPUIO: - reg += OMAP_MPUIO_IO_CNTL; - break; - case METHOD_GPIO_1510: - reg += OMAP1510_GPIO_DIR_CONTROL; - break; - case METHOD_GPIO_1610: - reg += OMAP1610_GPIO_DIRECTION; - break; - case METHOD_GPIO_730: - reg += OMAP730_GPIO_DIR_CONTROL; - break; - case METHOD_GPIO_850: - reg += OMAP850_GPIO_DIR_CONTROL; - break; - case METHOD_GPIO_24XX: - reg += OMAP24XX_GPIO_OE; - break; - } - return __raw_readl(reg) & mask; -} - - static int dbg_gpio_show(struct seq_file *s, void *unused) { unsigned i, j, gpio;