From mboxrd@z Thu Jan 1 00:00:00 1970 From: Axel Lin Subject: [PATCH RFT] gpio: zevio: Get correct gpio output value Date: Mon, 07 Apr 2014 14:34:52 +0800 Message-ID: <1396852492.26619.1.camel@phoenix> Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit Return-path: Received: from mail-pd0-f173.google.com ([209.85.192.173]:35452 "EHLO mail-pd0-f173.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751769AbaDGGfA (ORCPT ); Mon, 7 Apr 2014 02:35:00 -0400 Received: by mail-pd0-f173.google.com with SMTP id z10so6123112pdj.32 for ; Sun, 06 Apr 2014 23:35:00 -0700 (PDT) Sender: linux-gpio-owner@vger.kernel.org List-Id: linux-gpio@vger.kernel.org To: Linus Walleij , Alexandre Courbot Cc: Fabian Vogt , linux-gpio@vger.kernel.org Read gpio output value from ZEVIO_GPIO_OUTPUT. The spin_lock is required to ensure the direction is not changed before reading input/output value. Signed-off-by: Axel Lin --- Hi Fabian, The document only mentions: +10 (R/W): Direction (set bit to 0 for output, 1 for input) +14 (R/W): GPIO output bit +18 (R): Reads GPIO input bit. So I'm not sure if reading ZEVIO_GPIO_INPUT returns correct status when the direction is output. So I think this needs test. Regards, Axel drivers/gpio/gpio-zevio.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpio-zevio.c b/drivers/gpio/gpio-zevio.c index 9bf5034..29b0150 100644 --- a/drivers/gpio/gpio-zevio.c +++ b/drivers/gpio/gpio-zevio.c @@ -81,9 +81,15 @@ static inline void zevio_gpio_port_set(struct zevio_gpio *c, unsigned pin, static int zevio_gpio_get(struct gpio_chip *chip, unsigned pin) { struct zevio_gpio *controller = to_zevio_gpio(chip); + u32 val, dir; - /* Only reading allowed, so no spinlock needed */ - u32 val = zevio_gpio_port_get(controller, pin, ZEVIO_GPIO_INPUT); + spin_lock(&controller->lock); + dir = zevio_gpio_port_get(controller, pin, ZEVIO_GPIO_DIRECTION); + if (dir | BIT(ZEVIO_GPIO_BIT(pin))) + val = zevio_gpio_port_get(controller, pin, ZEVIO_GPIO_INPUT); + else + val = zevio_gpio_port_get(controller, pin, ZEVIO_GPIO_OUTPUT); + spin_unlock(&controller->lock); return (val >> ZEVIO_GPIO_BIT(pin)) & 0x1; } -- 1.8.3.2