From patchwork Wed Jan 10 22:44:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Jeffery X-Patchwork-Id: 858602 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zH3xs5KHhz9s7g for ; Thu, 11 Jan 2018 09:45:37 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=aj.id.au header.i=@aj.id.au header.b="VA2iM2ii"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="FITiM1H4"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3zH3xs3VkgzF0hJ for ; Thu, 11 Jan 2018 09:45:37 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=aj.id.au header.i=@aj.id.au header.b="VA2iM2ii"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="FITiM1H4"; dkim-atps=neutral X-Original-To: openbmc@lists.ozlabs.org Delivered-To: openbmc@lists.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=aj.id.au (client-ip=66.111.4.27; helo=out3-smtp.messagingengine.com; envelope-from=andrew@aj.id.au; receiver=) Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=aj.id.au header.i=@aj.id.au header.b="VA2iM2ii"; dkim=pass (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="FITiM1H4"; dkim-atps=neutral Received: from out3-smtp.messagingengine.com (out3-smtp.messagingengine.com [66.111.4.27]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3zH3xG36B3zF0gw for ; Thu, 11 Jan 2018 09:45:05 +1100 (AEDT) Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id 4741620CA5; Wed, 10 Jan 2018 17:45:02 -0500 (EST) Received: from frontend2 ([10.202.2.161]) by compute4.internal (MEProxy); Wed, 10 Jan 2018 17:45:02 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aj.id.au; h=cc :date:from:in-reply-to:message-id:references:subject:to :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=q0k+kndQu52rEQHyu F+xsfA5lKZMlQrWUQHvDk90O9A=; b=VA2iM2iiwMvTM7gEnMDWWztqALwJgFsWN rqKrcDPeUZoOmE3D/hKHd0SvXw9rtTN81fTUpLjKD6ClqPY8z3nh5DR1AjE7n006 5lTwh/FdiS20gVNQpnoKS5t8dTI8KT/6lXL0Swhc4L+d0KZ123HTA9v+DVlHhX16 HEhVQXdDtm9CE51DeDuophJuwIwF6+MghoAeJ5+y1LywMLC8UNj4T5KTOzsnt7ab W6WQvv4I3G/nO93BgSoOB5wjUqhHT2W7akdNvpxosnzmxmR2eS1eXDDhRwnHY5DF K1o/UptmsXHps5l9mkWv7Q4Fe1wnHeR3r0lH8PEKxtrCp/8Vf7PFA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:date:from:in-reply-to:message-id :references:subject:to:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; bh=q0k+kndQu52rEQHyuF+xsfA5lKZMlQrWUQHvDk90O9A=; b=FITiM1H4 OYJnrgok/WEu5wi+FgJkupCMfXtSne+E0/RVaMb805WjSr7pdXmeqAwbJiahp6MH 0XNrK1iKmDoCcIbfISu/E/Be2u9unPq9X5eHmiIxRkBYa1TRJ2icrCdx9om0XFe0 Ac67joC1xNuDfKxlS+b2mWie71TKomQXQvCa7p5MSXaxjvsc+fId8tJgZJ0ZpCXi 3FjKb8hEzj+/DLvINsfezPkdkHFdKy8dv41ICTXCt3LkSKLUAqWL6gUfHYHjgqCS 6B4qbRvkkun3ho1Tr1aOuD8FoFM3Tkm+418d7+/MJrkjkq8GyQPBsVwotJBSi8e4 ZNgCy9nTWmrh1A== X-ME-Sender: Received: from dave.google.com (unknown [104.133.8.110]) by mail.messagingengine.com (Postfix) with ESMTPA id 4241324235; Wed, 10 Jan 2018 17:45:01 -0500 (EST) From: Andrew Jeffery To: joel@jms.id.au Subject: [PATCH linux dev-4.10 1/4] gpiolib: Convert fwnode_get_named_gpiod() to configure GPIO Date: Wed, 10 Jan 2018 14:44:11 -0800 Message-Id: <20180110224414.21516-2-andrew@aj.id.au> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180110224414.21516-1-andrew@aj.id.au> References: <20180110224414.21516-1-andrew@aj.id.au> X-BeenThere: openbmc@lists.ozlabs.org X-Mailman-Version: 2.1.24 Precedence: list List-Id: Development list for OpenBMC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Andrew Jeffery , openbmc@lists.ozlabs.org, Andy Shevchenko Errors-To: openbmc-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "openbmc" From: Andy Shevchenko Make fwnode_get_named_gpiod() consistent with the rest of gpiod_get() like API, i.e. configure GPIO pin immediately after request. Besides obvious clean up it will help to configure pins based on firmware provided resources. Reviewed-by: Mika Westerberg Signed-off-by: Andy Shevchenko Signed-off-by: Linus Walleij (cherry picked from commit a264d10ff45c688293d9112fddd8d29c819e0853) Signed-off-by: Andrew Jeffery --- drivers/gpio/devres.c | 9 +++++++-- drivers/gpio/gpiolib.c | 20 ++++++++++++++++---- drivers/input/keyboard/gpio_keys.c | 9 +-------- drivers/input/keyboard/gpio_keys_polled.c | 11 ++--------- drivers/leds/leds-gpio.c | 2 +- drivers/video/fbdev/amba-clcd-nomadik.c | 15 +++++---------- include/linux/gpio/consumer.h | 19 +++++++++++++------ 7 files changed, 45 insertions(+), 40 deletions(-) diff --git a/drivers/gpio/devres.c b/drivers/gpio/devres.c index b760cbbb41d8..5e0b41b5e554 100644 --- a/drivers/gpio/devres.c +++ b/drivers/gpio/devres.c @@ -127,13 +127,18 @@ EXPORT_SYMBOL(devm_gpiod_get_index); * @dev: GPIO consumer * @con_id: function within the GPIO consumer * @child: firmware node (child of @dev) + * @flags: GPIO initialization flags * * GPIO descriptors returned from this function are automatically disposed on * driver detach. + * + * On successfull request the GPIO pin is configured in accordance with + * provided @flags. */ struct gpio_desc *devm_get_gpiod_from_child(struct device *dev, const char *con_id, - struct fwnode_handle *child) + struct fwnode_handle *child, + enum gpiod_flags flags) { static const char * const suffixes[] = { "gpios", "gpio" }; char prop_name[32]; /* 32 is max size of property name */ @@ -154,7 +159,7 @@ struct gpio_desc *devm_get_gpiod_from_child(struct device *dev, snprintf(prop_name, sizeof(prop_name), "%s", suffixes[i]); - desc = fwnode_get_named_gpiod(child, prop_name); + desc = fwnode_get_named_gpiod(child, prop_name, flags); if (!IS_ERR(desc) || (PTR_ERR(desc) != -ENOENT)) break; } diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index d0478f1853db..024f3a8bbf3b 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -3325,6 +3325,7 @@ EXPORT_SYMBOL_GPL(gpiod_get_index); * fwnode_get_named_gpiod - obtain a GPIO from firmware node * @fwnode: handle of the firmware node * @propname: name of the firmware property representing the GPIO + * @dflags: GPIO initialization flags * * This function can be used for drivers that get their configuration * from firmware. @@ -3333,12 +3334,17 @@ EXPORT_SYMBOL_GPL(gpiod_get_index); * underlying firmware interface and then makes sure that the GPIO * descriptor is requested before it is returned to the caller. * + * On successfull request the GPIO pin is configured in accordance with + * provided @dflags. + * * In case of error an ERR_PTR() is returned. */ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, - const char *propname) + const char *propname, + enum gpiod_flags dflags) { struct gpio_desc *desc = ERR_PTR(-ENODEV); + unsigned long lflags = 0; bool active_low = false; bool single_ended = false; int ret; @@ -3371,13 +3377,19 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, return ERR_PTR(ret); if (active_low) - set_bit(FLAG_ACTIVE_LOW, &desc->flags); + lflags |= GPIO_ACTIVE_LOW; if (single_ended) { if (active_low) - set_bit(FLAG_OPEN_DRAIN, &desc->flags); + lflags |= GPIO_OPEN_DRAIN; else - set_bit(FLAG_OPEN_SOURCE, &desc->flags); + lflags |= GPIO_OPEN_SOURCE; + } + + ret = gpiod_configure_flags(desc, propname, lflags, dflags); + if (ret < 0) { + gpiod_put(desc); + return ERR_PTR(ret); } return desc; diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c index 582462d0af75..9de4b876100a 100644 --- a/drivers/input/keyboard/gpio_keys.c +++ b/drivers/input/keyboard/gpio_keys.c @@ -481,7 +481,7 @@ static int gpio_keys_setup_key(struct platform_device *pdev, spin_lock_init(&bdata->lock); if (child) { - bdata->gpiod = devm_get_gpiod_from_child(dev, NULL, child); + bdata->gpiod = devm_get_gpiod_from_child(dev, NULL, child, GPIOD_IN); if (IS_ERR(bdata->gpiod)) { error = PTR_ERR(bdata->gpiod); if (error == -ENOENT) { @@ -496,13 +496,6 @@ static int gpio_keys_setup_key(struct platform_device *pdev, error); return error; } - } else { - error = gpiod_direction_input(bdata->gpiod); - if (error) { - dev_err(dev, "Failed to configure GPIO %d as input: %d\n", - desc_to_gpio(bdata->gpiod), error); - return error; - } } } else if (gpio_is_valid(button->gpio)) { /* diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c index bed4f2086158..fd7ab4dad87b 100644 --- a/drivers/input/keyboard/gpio_keys_polled.c +++ b/drivers/input/keyboard/gpio_keys_polled.c @@ -304,7 +304,8 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) } bdata->gpiod = devm_get_gpiod_from_child(dev, NULL, - child); + child, + GPIOD_IN); if (IS_ERR(bdata->gpiod)) { error = PTR_ERR(bdata->gpiod); if (error != -EPROBE_DEFER) @@ -314,14 +315,6 @@ static int gpio_keys_polled_probe(struct platform_device *pdev) fwnode_handle_put(child); return error; } - - error = gpiod_direction_input(bdata->gpiod); - if (error) { - dev_err(dev, "Failed to configure GPIO %d as input: %d\n", - desc_to_gpio(bdata->gpiod), error); - fwnode_handle_put(child); - return error; - } } else if (gpio_is_valid(button->gpio)) { /* * Legacy GPIO number so request the GPIO here and diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index 061ab9220048..7fcca92b2fcd 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c @@ -176,7 +176,7 @@ static struct gpio_leds_priv *gpio_leds_create(struct platform_device *pdev) const char *state = NULL; struct device_node *np = to_of_node(child); - led.gpiod = devm_get_gpiod_from_child(dev, NULL, child); + led.gpiod = devm_get_gpiod_from_child(dev, NULL, child, GPIOD_ASIS); if (IS_ERR(led.gpiod)) { fwnode_handle_put(child); return ERR_CAST(led.gpiod); diff --git a/drivers/video/fbdev/amba-clcd-nomadik.c b/drivers/video/fbdev/amba-clcd-nomadik.c index 0c06fcaaa6e8..2e800d70b0e5 100644 --- a/drivers/video/fbdev/amba-clcd-nomadik.c +++ b/drivers/video/fbdev/amba-clcd-nomadik.c @@ -184,32 +184,27 @@ static void tpg110_init(struct device *dev, struct device_node *np, { dev_info(dev, "TPG110 display init\n"); - grestb = devm_get_gpiod_from_child(dev, "grestb", &np->fwnode); + /* This asserts the GRESTB signal, putting the display into reset */ + grestb = devm_get_gpiod_from_child(dev, "grestb", &np->fwnode, GPIOD_OUT_HIGH); if (IS_ERR(grestb)) { dev_err(dev, "no GRESTB GPIO\n"); return; } - /* This asserts the GRESTB signal, putting the display into reset */ - gpiod_direction_output(grestb, 1); - - scen = devm_get_gpiod_from_child(dev, "scen", &np->fwnode); + scen = devm_get_gpiod_from_child(dev, "scen", &np->fwnode, GPIOD_OUT_LOW); if (IS_ERR(scen)) { dev_err(dev, "no SCEN GPIO\n"); return; } - gpiod_direction_output(scen, 0); - scl = devm_get_gpiod_from_child(dev, "scl", &np->fwnode); + scl = devm_get_gpiod_from_child(dev, "scl", &np->fwnode, GPIOD_OUT_LOW); if (IS_ERR(scl)) { dev_err(dev, "no SCL GPIO\n"); return; } - gpiod_direction_output(scl, 0); - sda = devm_get_gpiod_from_child(dev, "sda", &np->fwnode); + sda = devm_get_gpiod_from_child(dev, "sda", &np->fwnode, GPIOD_OUT_LOW); if (IS_ERR(sda)) { dev_err(dev, "no SDA GPIO\n"); return; } - gpiod_direction_output(sda, 0); board->enable = tpg110_enable; board->disable = tpg110_disable; } diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h index fb0fde686cb1..930d10049d8d 100644 --- a/include/linux/gpio/consumer.h +++ b/include/linux/gpio/consumer.h @@ -135,10 +135,12 @@ int desc_to_gpio(const struct gpio_desc *desc); struct fwnode_handle; struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, - const char *propname); + const char *propname, + enum gpiod_flags dflags); struct gpio_desc *devm_get_gpiod_from_child(struct device *dev, const char *con_id, - struct fwnode_handle *child); + struct fwnode_handle *child, + enum gpiod_flags flags); #else /* CONFIG_GPIOLIB */ static inline int gpiod_count(struct device *dev, const char *con_id) @@ -411,14 +413,19 @@ static inline int desc_to_gpio(const struct gpio_desc *desc) /* Child properties interface */ struct fwnode_handle; -static inline struct gpio_desc *fwnode_get_named_gpiod( - struct fwnode_handle *fwnode, const char *propname) +static inline +struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, + const char *propname, + enum gpiod_flags dflags) { return ERR_PTR(-ENOSYS); } -static inline struct gpio_desc *devm_get_gpiod_from_child( - struct device *dev, const char *con_id, struct fwnode_handle *child) +static inline +struct gpio_desc *devm_get_gpiod_from_child(struct device *dev, + const char *con_id, + struct fwnode_handle *child, + enum gpiod_flags flags) { return ERR_PTR(-ENOSYS); } From patchwork Wed Jan 10 22:44:12 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Jeffery X-Patchwork-Id: 858603 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zH3yD05cZz9s7g for ; Thu, 11 Jan 2018 09:45:56 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=aj.id.au header.i=@aj.id.au header.b="peVcOU3i"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="XLXIWWXs"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3zH3yC4mKYzF0h1 for ; Thu, 11 Jan 2018 09:45:55 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=aj.id.au header.i=@aj.id.au header.b="peVcOU3i"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="XLXIWWXs"; dkim-atps=neutral X-Original-To: openbmc@lists.ozlabs.org Delivered-To: openbmc@lists.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=aj.id.au (client-ip=66.111.4.27; helo=out3-smtp.messagingengine.com; envelope-from=andrew@aj.id.au; receiver=) Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=aj.id.au header.i=@aj.id.au header.b="peVcOU3i"; dkim=pass (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="XLXIWWXs"; dkim-atps=neutral Received: from out3-smtp.messagingengine.com (out3-smtp.messagingengine.com [66.111.4.27]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3zH3xG31P4zF0gj for ; Thu, 11 Jan 2018 09:45:05 +1100 (AEDT) Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id D9E0E20BEB; Wed, 10 Jan 2018 17:45:02 -0500 (EST) Received: from frontend2 ([10.202.2.161]) by compute4.internal (MEProxy); Wed, 10 Jan 2018 17:45:02 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aj.id.au; h=cc :date:from:in-reply-to:message-id:references:subject:to :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=HWRsrV4JjNamzGPAn bijFJjS34AOz3wjnqnT4BQiU80=; b=peVcOU3i7TMdi0qUd5CYVV22uPEte/0Z3 3QNiQuyGLn/D0WffZX/iiBf8EKrAAIOUcQ7Z1gULBRMixpb2rP97MwOyRKZ54MHo Z/waKz6pd8CuIwEFaowkqMiUop180TipKLMolFIGRvNEG8iD7QoosfWscnuL8nvm JLfcrTeD9n2sE1T7FLUVUi0tV3epdnQpd6mxd5M/Sny62rEfrHJUClO6HeN6eKW7 hKmolzn1d9wbAnDQhiKB6ayu4SZaOnbd4q8G03iva4S2IVM1TBuG2XuRLWFRgqh/ WUsJkT733Fw7ul34xZ4iIJEEcPW7dVX3E9dTIYFaop6nAxAoibnQg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:date:from:in-reply-to:message-id :references:subject:to:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; bh=HWRsrV4JjNamzGPAnbijFJjS34AOz3wjnqnT4BQiU80=; b=XLXIWWXs NepRPIqyGfP4Qh6NedyAF2CnCg1cSIyTdXPLmZxZ6JF88X2icy5njrLHjA8nFBob Micuzbhb0i594PL9ztbEP0/WNWsuIjhS+xssedkJCmUUb7R0oicZbdv56qR9cbSh 4ebmKQUsoNF+EJE2RvDGQEi4lkGiXIE1ZSz3dDmNVbTIVldWeB52anTYazsidc19 b2uWZDlPZ4fjJ2gZmE2I4reXtQPay/0TTX3/w0GCdJt4RJ2URmiGgf8WABdp6cbD DYmKmZ0vL0YCA85a45mMg9JsZbYS3wDBxDO72Ug+KH0db79sirHl74Pd+YTe0DqP 8lLDhUhGGQHcrw== X-ME-Sender: Received: from dave.google.com (unknown [104.133.8.110]) by mail.messagingengine.com (Postfix) with ESMTPA id 2FCA724802; Wed, 10 Jan 2018 17:45:02 -0500 (EST) From: Andrew Jeffery To: joel@jms.id.au Subject: [PATCH linux dev-4.10 2/4] gpio: core: Decouple open drain/source flag with active low/high Date: Wed, 10 Jan 2018 14:44:12 -0800 Message-Id: <20180110224414.21516-3-andrew@aj.id.au> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180110224414.21516-1-andrew@aj.id.au> References: <20180110224414.21516-1-andrew@aj.id.au> X-BeenThere: openbmc@lists.ozlabs.org X-Mailman-Version: 2.1.24 Precedence: list List-Id: Development list for OpenBMC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Andrew Jeffery , openbmc@lists.ozlabs.org, Laxman Dewangan Errors-To: openbmc-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "openbmc" From: Laxman Dewangan Currently, the GPIO interface is said to Open Drain if it is Single Ended and active LOW. Similarly, it is said as Open Source if it is Single Ended and active HIGH. The active HIGH/LOW is used in the interface for setting the pin state to HIGH or LOW when enabling/disabling the interface. In Open Drain interface, pin is set to HIGH by putting pin in high impedance and LOW by driving to the LOW. In Open Source interface, pin is set to HIGH by driving pin to HIGH and set to LOW by putting pin in high impedance. With above, the Open Drain/Source is unrelated to the active LOW/HIGH in interface. There is interface where the enable/disable of interface is ether active LOW or HIGH but it is Open Drain type. Hence decouple the Open Drain with Single Ended + Active LOW and Open Source with Single Ended + Active HIGH. Adding different flag for the Open Drain/Open Source which is valid only when Single ended flag is enabled. Signed-off-by: Laxman Dewangan Signed-off-by: Linus Walleij (cherry picked from commit 4c0facddb7d88c78c8bd977c16faa647f079ccda) Signed-off-by: Andrew Jeffery --- drivers/gpio/gpiolib-of.c | 2 +- drivers/gpio/gpiolib.c | 4 +++- include/dt-bindings/gpio/gpio.h | 12 ++++++++---- include/linux/of_gpio.h | 1 + 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index 92b185f19232..ebe82758e768 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -147,7 +147,7 @@ struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id, *flags |= GPIO_ACTIVE_LOW; if (of_flags & OF_GPIO_SINGLE_ENDED) { - if (of_flags & OF_GPIO_ACTIVE_LOW) + if (of_flags & OF_GPIO_OPEN_DRAIN) *flags |= GPIO_OPEN_DRAIN; else *flags |= GPIO_OPEN_SOURCE; diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 024f3a8bbf3b..e4796fbaeb4b 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -3347,6 +3347,7 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, unsigned long lflags = 0; bool active_low = false; bool single_ended = false; + bool open_drain = false; int ret; if (!fwnode) @@ -3360,6 +3361,7 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, if (!IS_ERR(desc)) { active_low = flags & OF_GPIO_ACTIVE_LOW; single_ended = flags & OF_GPIO_SINGLE_ENDED; + open_drain = flags & OF_GPIO_OPEN_DRAIN; } } else if (is_acpi_node(fwnode)) { struct acpi_gpio_info info; @@ -3380,7 +3382,7 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, lflags |= GPIO_ACTIVE_LOW; if (single_ended) { - if (active_low) + if (open_drain) lflags |= GPIO_OPEN_DRAIN; else lflags |= GPIO_OPEN_SOURCE; diff --git a/include/dt-bindings/gpio/gpio.h b/include/dt-bindings/gpio/gpio.h index c673d2c87c60..b4f54da694eb 100644 --- a/include/dt-bindings/gpio/gpio.h +++ b/include/dt-bindings/gpio/gpio.h @@ -17,11 +17,15 @@ #define GPIO_PUSH_PULL 0 #define GPIO_SINGLE_ENDED 2 +/* Bit 2 express Open drain or open source */ +#define GPIO_LINE_OPEN_SOURCE 0 +#define GPIO_LINE_OPEN_DRAIN 4 + /* - * Open Drain/Collector is the combination of single-ended active low, - * Open Source/Emitter is the combination of single-ended active high. + * Open Drain/Collector is the combination of single-ended open drain interface. + * Open Source/Emitter is the combination of single-ended open source interface. */ -#define GPIO_OPEN_DRAIN (GPIO_SINGLE_ENDED | GPIO_ACTIVE_LOW) -#define GPIO_OPEN_SOURCE (GPIO_SINGLE_ENDED | GPIO_ACTIVE_HIGH) +#define GPIO_OPEN_DRAIN (GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_DRAIN) +#define GPIO_OPEN_SOURCE (GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_SOURCE) #endif diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h index 3f87ea5b8bee..1e089d5a182b 100644 --- a/include/linux/of_gpio.h +++ b/include/linux/of_gpio.h @@ -30,6 +30,7 @@ struct device_node; enum of_gpio_flags { OF_GPIO_ACTIVE_LOW = 0x1, OF_GPIO_SINGLE_ENDED = 0x2, + OF_GPIO_OPEN_DRAIN = 0x4, }; #ifdef CONFIG_OF_GPIO From patchwork Wed Jan 10 22:44:13 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Jeffery X-Patchwork-Id: 858604 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zH3z23WQzz9s7g for ; Thu, 11 Jan 2018 09:46:38 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=aj.id.au header.i=@aj.id.au header.b="DyfbKVEg"; dkim=pass (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="fizwn+wx"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3zH3z20D89zF0h1 for ; Thu, 11 Jan 2018 09:46:38 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=aj.id.au header.i=@aj.id.au header.b="DyfbKVEg"; dkim=pass (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="fizwn+wx"; dkim-atps=neutral X-Original-To: openbmc@lists.ozlabs.org Delivered-To: openbmc@lists.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=aj.id.au (client-ip=66.111.4.27; helo=out3-smtp.messagingengine.com; envelope-from=andrew@aj.id.au; receiver=) Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=aj.id.au header.i=@aj.id.au header.b="DyfbKVEg"; dkim=pass (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="fizwn+wx"; dkim-atps=neutral Received: from out3-smtp.messagingengine.com (out3-smtp.messagingengine.com [66.111.4.27]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3zH3xG331NzF0gs for ; Thu, 11 Jan 2018 09:45:05 +1100 (AEDT) Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id 7FD3620BA8; Wed, 10 Jan 2018 17:45:03 -0500 (EST) Received: from frontend2 ([10.202.2.161]) by compute4.internal (MEProxy); Wed, 10 Jan 2018 17:45:03 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aj.id.au; h=cc :date:from:in-reply-to:message-id:references:subject:to :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=NARjfowiMRHp47xsF QKlnIaQqkkL+Ys0ZlSkT0v0/tQ=; b=DyfbKVEg02qLbzj7LwrKZnuyCkjHDl/el qq4T7ndVQX4gXv0Q8Dvchh/bpgev7j/+Gw8oJsbAjlcynOqz+o9JSC7H54Px66ut wXKq6YkXwAP3qBpNxDqHwzMcmcJXe6VidewutLRKPObHzY4moPXpbBwK5mmWPz57 ynR0EgAln9nzyqwH0RcEME8IMq8IllPr4d7s8uR9sx7koDg635Vyv6GmfJdWurIa Who2LHc2syJRRRgI0noXlTmu0Q7TSwl8Obl6FHeRmhohQfJbwIlpKUU91ursUMam FRjNIX2fa/HGGO0ZbLVRDWjI4T5e9qDm2R9qYOyyYnYiPDV+2G12A== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:date:from:in-reply-to:message-id :references:subject:to:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; bh=NARjfowiMRHp47xsFQKlnIaQqkkL+Ys0ZlSkT0v0/tQ=; b=fizwn+wx 4iOmj+ICQHoGM1/lQgfgJ9BUZgvHcpeATUk1t+eQyLXtYw0yywU2PsObbuHVVT7V TlOaRF/2c4MCkEp8bKMprB8HjXdf2SfGiOfL4UuYdLVgec5julrK7wCDq+fRM6vq ziqB8Kf+2SPw488tfKeeAE3TVuuh3wm5JOa2eLRaZWN2nKS9/A5ueynlx2QY/Hk0 OPqBI+aWVFFx2Min+Cq5DVMFAHoFMbBXgJDlNqUXNXsPnWQ1go169Dxd0fRe7tU0 LY78kdgt0Qm5fggSZ2IRtXeNwQKDb0Yq5DMeH5PVbJQFjIXtuXvo6oIXrONutZ72 IurnySF+x5qeCw== X-ME-Sender: Received: from dave.google.com (unknown [104.133.8.110]) by mail.messagingengine.com (Postfix) with ESMTPA id CFC99246CA; Wed, 10 Jan 2018 17:45:02 -0500 (EST) From: Andrew Jeffery To: joel@jms.id.au Subject: [PATCH linux dev-4.10 3/4] gpio: gpiolib: Generalise state persistence beyond sleep Date: Wed, 10 Jan 2018 14:44:13 -0800 Message-Id: <20180110224414.21516-4-andrew@aj.id.au> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180110224414.21516-1-andrew@aj.id.au> References: <20180110224414.21516-1-andrew@aj.id.au> X-BeenThere: openbmc@lists.ozlabs.org X-Mailman-Version: 2.1.24 Precedence: list List-Id: Development list for OpenBMC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Andrew Jeffery , openbmc@lists.ozlabs.org Errors-To: openbmc-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "openbmc" General support for state persistence is added to gpiolib with the introduction of a new pinconf parameter to propagate the request to hardware. The existing persistence support for sleep is adapted to include hardware support if the GPIO driver provides it. Persistence continues to be enabled by default; in-kernel consumers can opt out, but userspace (currently) does not have a choice. The *_SLEEP_MAY_LOSE_VALUE and *_SLEEP_MAINTAIN_VALUE symbols are renamed, dropping the SLEEP prefix to reflect that the concept is no longer sleep-specific. I feel that renaming to just *_MAY_LOSE_VALUE could initially be misinterpreted, so I've further changed the symbols to *_TRANSITORY and *_PERSISTENT to address this. The sysfs interface is modified only to keep consistency with the chardev interface in enforcing persistence for userspace exports. Signed-off-by: Andrew Jeffery Reviewed-by: Charles Keepax Acked-by: Rob Herring Signed-off-by: Linus Walleij (cherry picked from commit e10f72bf4b3e8885c1915a119141481e7fc45ca8) --- drivers/gpio/gpiolib-of.c | 5 +++ drivers/gpio/gpiolib-sysfs.c | 14 ++++--- drivers/gpio/gpiolib.c | 65 +++++++++++++++++++++++++++++++++ drivers/gpio/gpiolib.h | 1 + include/dt-bindings/gpio/gpio.h | 4 ++ include/linux/gpio/consumer.h | 8 ++++ include/linux/gpio/machine.h | 2 + include/linux/of_gpio.h | 1 + include/linux/pinctrl/pinconf-generic.h | 10 ++++- 9 files changed, 104 insertions(+), 6 deletions(-) diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index ebe82758e768..86836dbba284 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -153,6 +153,9 @@ struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id, *flags |= GPIO_OPEN_SOURCE; } + if (of_flags & OF_GPIO_TRANSITORY) + *flags |= GPIO_TRANSITORY; + return desc; } @@ -206,6 +209,8 @@ static struct gpio_desc *of_parse_own_gpio(struct device_node *np, if (xlate_flags & OF_GPIO_ACTIVE_LOW) *lflags |= GPIO_ACTIVE_LOW; + if (xlate_flags & OF_GPIO_TRANSITORY) + *lflags |= GPIO_TRANSITORY; if (of_property_read_bool(np, "input")) *dflags |= GPIOD_IN; diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c index 4b44dd97c07f..9df5db82035a 100644 --- a/drivers/gpio/gpiolib-sysfs.c +++ b/drivers/gpio/gpiolib-sysfs.c @@ -468,11 +468,15 @@ static ssize_t export_store(struct class *class, status = -ENODEV; goto done; } - status = gpiod_export(desc, true); - if (status < 0) - gpiod_free(desc); - else - set_bit(FLAG_SYSFS, &desc->flags); + + status = gpiod_set_transitory(desc, false); + if (!status) { + status = gpiod_export(desc, true); + if (status < 0) + gpiod_free(desc); + else + set_bit(FLAG_SYSFS, &desc->flags); + } done: if (status) diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index e4796fbaeb4b..81af68ce66dd 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -479,6 +479,10 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) if (lflags & GPIOHANDLE_REQUEST_OPEN_SOURCE) set_bit(FLAG_OPEN_SOURCE, &desc->flags); + ret = gpiod_set_transitory(desc, false); + if (ret < 0) + goto out_free_descs; + /* * Lines have to be requested explicitly for input * or output, else the line will be treated "as is". @@ -2406,6 +2410,49 @@ int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce) } EXPORT_SYMBOL_GPL(gpiod_set_debounce); +/** + * gpiod_set_transitory - Lose or retain GPIO state on suspend or reset + * @desc: descriptor of the GPIO for which to configure persistence + * @transitory: True to lose state on suspend or reset, false for persistence + * + * Returns: + * 0 on success, otherwise a negative error code. + */ +int gpiod_set_transitory(struct gpio_desc *desc, bool transitory) +{ + struct gpio_chip *chip; + unsigned long packed; + int gpio; + int rc; + + /* + * Handle FLAG_TRANSITORY first, enabling queries to gpiolib for + * persistence state. + */ + if (transitory) + set_bit(FLAG_TRANSITORY, &desc->flags); + else + clear_bit(FLAG_TRANSITORY, &desc->flags); + + /* If the driver supports it, set the persistence state now */ + chip = desc->gdev->chip; + if (!chip->set_config) + return 0; + + packed = pinconf_to_config_packed(PIN_CONFIG_PERSIST_STATE, + !transitory); + gpio = gpio_chip_hwgpio(desc); + rc = chip->set_config(chip, gpio, packed); + if (rc == -ENOTSUPP) { + dev_dbg(&desc->gdev->dev, "Persistence not supported for GPIO %d\n", + gpio); + return 0; + } + + return rc; +} +EXPORT_SYMBOL_GPL(gpiod_set_transitory); + /** * gpiod_is_active_low - test whether a GPIO is active-low or not * @desc: the gpio descriptor to test @@ -2885,6 +2932,15 @@ bool gpiochip_line_is_open_source(struct gpio_chip *chip, unsigned int offset) } EXPORT_SYMBOL_GPL(gpiochip_line_is_open_source); +bool gpiochip_line_is_persistent(struct gpio_chip *chip, unsigned int offset) +{ + if (offset >= chip->ngpio) + return false; + + return !test_bit(FLAG_TRANSITORY, &chip->gpiodev->descs[offset].flags); +} +EXPORT_SYMBOL_GPL(gpiochip_line_is_persistent); + /** * gpiod_get_raw_value_cansleep() - return a gpio's raw value * @desc: gpio whose value will be returned @@ -3240,6 +3296,10 @@ static int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id, if (lflags & GPIO_OPEN_SOURCE) set_bit(FLAG_OPEN_SOURCE, &desc->flags); + status = gpiod_set_transitory(desc, (lflags & GPIO_TRANSITORY)); + if (status < 0) + return status; + /* No particular flag request, return here... */ if (!(dflags & GPIOD_FLAGS_BIT_DIR_SET)) { pr_debug("no flags found for %s\n", con_id); @@ -3348,6 +3408,7 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, bool active_low = false; bool single_ended = false; bool open_drain = false; + bool transitory = false; int ret; if (!fwnode) @@ -3362,6 +3423,7 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, active_low = flags & OF_GPIO_ACTIVE_LOW; single_ended = flags & OF_GPIO_SINGLE_ENDED; open_drain = flags & OF_GPIO_OPEN_DRAIN; + transitory = flags & OF_GPIO_TRANSITORY; } } else if (is_acpi_node(fwnode)) { struct acpi_gpio_info info; @@ -3388,6 +3450,9 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode, lflags |= GPIO_OPEN_SOURCE; } + if (transitory) + lflags |= GPIO_TRANSITORY; + ret = gpiod_configure_flags(desc, propname, lflags, dflags); if (ret < 0) { gpiod_put(desc); diff --git a/drivers/gpio/gpiolib.h b/drivers/gpio/gpiolib.h index d10eaf520860..263359bca527 100644 --- a/drivers/gpio/gpiolib.h +++ b/drivers/gpio/gpiolib.h @@ -189,6 +189,7 @@ struct gpio_desc { #define FLAG_OPEN_SOURCE 8 /* Gpio is open source type */ #define FLAG_USED_AS_IRQ 9 /* GPIO is connected to an IRQ */ #define FLAG_IS_HOGGED 11 /* GPIO is hogged */ +#define FLAG_TRANSITORY 12 /* GPIO may lose value in sleep or reset */ /* Connection label */ const char *label; diff --git a/include/dt-bindings/gpio/gpio.h b/include/dt-bindings/gpio/gpio.h index b4f54da694eb..43dc230d3921 100644 --- a/include/dt-bindings/gpio/gpio.h +++ b/include/dt-bindings/gpio/gpio.h @@ -28,4 +28,8 @@ #define GPIO_OPEN_DRAIN (GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_DRAIN) #define GPIO_OPEN_SOURCE (GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_SOURCE) +/* Bit 3 express GPIO suspend/resume and reset persistence */ +#define GPIO_PERSISTENT 0 +#define GPIO_TRANSITORY 8 + #endif diff --git a/include/linux/gpio/consumer.h b/include/linux/gpio/consumer.h index 930d10049d8d..f10d51433fbf 100644 --- a/include/linux/gpio/consumer.h +++ b/include/linux/gpio/consumer.h @@ -121,6 +121,7 @@ void gpiod_set_raw_array_value_cansleep(unsigned int array_size, int *value_array); int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce); +int gpiod_set_transitory(struct gpio_desc *desc, bool transitory); int gpiod_is_active_low(const struct gpio_desc *desc); int gpiod_cansleep(const struct gpio_desc *desc); @@ -378,6 +379,13 @@ static inline int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce) return -ENOSYS; } +static inline int gpiod_set_transitory(struct gpio_desc *desc, bool transitory) +{ + /* GPIO can never have been requested */ + WARN_ON(1); + return -ENOSYS; +} + static inline int gpiod_is_active_low(const struct gpio_desc *desc) { /* GPIO can never have been requested */ diff --git a/include/linux/gpio/machine.h b/include/linux/gpio/machine.h index c0d712d22b07..f617fd163e1f 100644 --- a/include/linux/gpio/machine.h +++ b/include/linux/gpio/machine.h @@ -9,6 +9,8 @@ enum gpio_lookup_flags { GPIO_ACTIVE_LOW = (1 << 0), GPIO_OPEN_DRAIN = (1 << 1), GPIO_OPEN_SOURCE = (1 << 2), + GPIO_PERSISTENT = (0 << 3), + GPIO_TRANSITORY = (1 << 3), }; /** diff --git a/include/linux/of_gpio.h b/include/linux/of_gpio.h index 1e089d5a182b..18a7f03e1182 100644 --- a/include/linux/of_gpio.h +++ b/include/linux/of_gpio.h @@ -31,6 +31,7 @@ enum of_gpio_flags { OF_GPIO_ACTIVE_LOW = 0x1, OF_GPIO_SINGLE_ENDED = 0x2, OF_GPIO_OPEN_DRAIN = 0x4, + OF_GPIO_TRANSITORY = 0x8, }; #ifdef CONFIG_OF_GPIO diff --git a/include/linux/pinctrl/pinconf-generic.h b/include/linux/pinctrl/pinconf-generic.h index 763dcd68e66b..e00bd58b3dd2 100644 --- a/include/linux/pinctrl/pinconf-generic.h +++ b/include/linux/pinctrl/pinconf-generic.h @@ -83,6 +83,11 @@ * @PIN_CONFIG_SLEW_RATE: if the pin can select slew rate, the argument to * this parameter (on a custom format) tells the driver which alternative * slew rate to use. + * @PIN_CONFIG_SKEW_DELAY: if the pin has programmable skew rate (on inputs) + * or latch delay (on outputs) this parameter (in a custom format) + * specifies the clock skew or latch delay. It typically controls how + * many double inverters are put in front of the line. + * @PIN_CONFIG_PERSIST_STATE: retain pin state across sleep or controller reset * @PIN_CONFIG_END: this is the last enumerator for pin configurations, if * you need to pass in custom configurations to the pin controller, use * PIN_CONFIG_END+1 as the base offset. @@ -106,7 +111,10 @@ enum pin_config_param { PIN_CONFIG_OUTPUT, PIN_CONFIG_POWER_SOURCE, PIN_CONFIG_SLEW_RATE, - PIN_CONFIG_END = 0x7FFF, + PIN_CONFIG_SKEW_DELAY, + PIN_CONFIG_PERSIST_STATE, + PIN_CONFIG_END = 0x7F, + PIN_CONFIG_MAX = 0xFF, }; /* From patchwork Wed Jan 10 22:44:14 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Jeffery X-Patchwork-Id: 858605 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zH3zM12c9z9sNr for ; Thu, 11 Jan 2018 09:46:55 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=aj.id.au header.i=@aj.id.au header.b="dRZdIck9"; dkim=pass (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="YN9RqfpB"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3zH3zL5g0FzF0kW for ; Thu, 11 Jan 2018 09:46:54 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=aj.id.au header.i=@aj.id.au header.b="dRZdIck9"; dkim=pass (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="YN9RqfpB"; dkim-atps=neutral X-Original-To: openbmc@lists.ozlabs.org Delivered-To: openbmc@lists.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=aj.id.au (client-ip=66.111.4.27; helo=out3-smtp.messagingengine.com; envelope-from=andrew@aj.id.au; receiver=) Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=aj.id.au header.i=@aj.id.au header.b="dRZdIck9"; dkim=pass (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="YN9RqfpB"; dkim-atps=neutral Received: from out3-smtp.messagingengine.com (out3-smtp.messagingengine.com [66.111.4.27]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3zH3xG2z70zF0gV for ; Thu, 11 Jan 2018 09:45:06 +1100 (AEDT) Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id 1D0AF20C6E; Wed, 10 Jan 2018 17:45:04 -0500 (EST) Received: from frontend2 ([10.202.2.161]) by compute4.internal (MEProxy); Wed, 10 Jan 2018 17:45:04 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aj.id.au; h=cc :date:from:in-reply-to:message-id:references:subject:to :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=Vr3buhyuvjIbVlDzy FZlWN4Jms/nvbi2hRT10V7LQK0=; b=dRZdIck9tVciotP3jI67Fc71BYRWQbl2I i9bsPvPamV6j19R6X9o+Uk/AM0NZJM7jsLKnkNXKETphpg+D0jU8N8ntc2kxxUzN TYqT43zXfWHTDlChPfe6On5W+DgoqnCcfs5JLrwVrNYkneOZf1E9LTsxH4ykwUjm J8p4WiJEfS9+81XAx7QXGzUgoyyAZ956NSpG/Jfs5aq8FBcaME7g//Dto8kp6ysq Uyl8MdgYqPskpm8xcRf24DqNruhsMyGQEvY2ArSYghj6pS+cKbcTI0ofBvQG6QN2 +DXVNW8MpcGqzZrbdq9S4hFMrJ51G2O1r+SuqIGAHgn7omHgqfhvQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:date:from:in-reply-to:message-id :references:subject:to:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; bh=Vr3buhyuvjIbVlDzyFZlWN4Jms/nvbi2hRT10V7LQK0=; b=YN9RqfpB GMNnbj6zjtX6TWsovXU5a4WII0RWOOxRJKXKxge9tZVRFUssXK4PRxjcnOFWVzQi oaP8cFkdNPSrhAajwJOkVFOfC5zyPBkDZ1y2i1GhcO+XzXlUVJju/D3OP7d1W8iV xMnIReIzNLItGNzAgOdE5Nbrc0xhwoloM3EI+RIMSlV9kZGqPk5s9FERPjFTgpcy NKxMKocRrl2c55le5MJdZJ+eF4Up2MgKPt0NDNLgLhet/jBnEbeLxL+x17Zr8S1a Lj9DZZvE9ISEGkzoUEm4ywpFIe0tGrBV0X21E1jjLsplkMXG5Cwc5vp4n7wLIb/S JdE8cQrdwdprtA== X-ME-Sender: Received: from dave.google.com (unknown [104.133.8.110]) by mail.messagingengine.com (Postfix) with ESMTPA id 78D8E24805; Wed, 10 Jan 2018 17:45:03 -0500 (EST) From: Andrew Jeffery To: joel@jms.id.au Subject: [PATCH linux dev-4.10 4/4] gpio: aspeed: Add support for reset tolerance Date: Wed, 10 Jan 2018 14:44:14 -0800 Message-Id: <20180110224414.21516-5-andrew@aj.id.au> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180110224414.21516-1-andrew@aj.id.au> References: <20180110224414.21516-1-andrew@aj.id.au> X-BeenThere: openbmc@lists.ozlabs.org X-Mailman-Version: 2.1.24 Precedence: list List-Id: Development list for OpenBMC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Andrew Jeffery , openbmc@lists.ozlabs.org Errors-To: openbmc-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "openbmc" Use the new pinconf parameter for state persistence to expose the associated capability of the Aspeed GPIO controller. Signed-off-by: Andrew Jeffery Reviewed-by: Joel Stanley Signed-off-by: Linus Walleij (cherry picked from commit 1b43d26985745901c87e0dca44c9b57896062306) --- drivers/gpio/gpio-aspeed.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c index ccea609676ee..97e083aadc16 100644 --- a/drivers/gpio/gpio-aspeed.c +++ b/drivers/gpio/gpio-aspeed.c @@ -60,6 +60,7 @@ struct aspeed_gpio_bank { uint16_t val_regs; uint16_t irq_regs; uint16_t debounce_regs; + uint16_t tolerance_regs; const char names[4][3]; }; @@ -70,48 +71,56 @@ static const struct aspeed_gpio_bank aspeed_gpio_banks[] = { .val_regs = 0x0000, .irq_regs = 0x0008, .debounce_regs = 0x0040, + .tolerance_regs = 0x001c, .names = { "A", "B", "C", "D" }, }, { .val_regs = 0x0020, .irq_regs = 0x0028, .debounce_regs = 0x0048, + .tolerance_regs = 0x003c, .names = { "E", "F", "G", "H" }, }, { .val_regs = 0x0070, .irq_regs = 0x0098, .debounce_regs = 0x00b0, + .tolerance_regs = 0x00ac, .names = { "I", "J", "K", "L" }, }, { .val_regs = 0x0078, .irq_regs = 0x00e8, .debounce_regs = 0x0100, + .tolerance_regs = 0x00fc, .names = { "M", "N", "O", "P" }, }, { .val_regs = 0x0080, .irq_regs = 0x0118, .debounce_regs = 0x0130, + .tolerance_regs = 0x012c, .names = { "Q", "R", "S", "T" }, }, { .val_regs = 0x0088, .irq_regs = 0x0148, .debounce_regs = 0x0160, + .tolerance_regs = 0x015c, .names = { "U", "V", "W", "X" }, }, { .val_regs = 0x01E0, .irq_regs = 0x0178, .debounce_regs = 0x0190, + .tolerance_regs = 0x018c, .names = { "Y", "Z", "AA", "AB" }, }, { - .val_regs = 0x01E8, - .irq_regs = 0x01A8, + .val_regs = 0x01e8, + .irq_regs = 0x01a8, .debounce_regs = 0x01c0, + .tolerance_regs = 0x01bc, .names = { "AC", "", "", "" }, }, }; @@ -531,6 +540,30 @@ static int aspeed_gpio_setup_irqs(struct aspeed_gpio *gpio, return 0; } +static int aspeed_gpio_reset_tolerance(struct gpio_chip *chip, + unsigned int offset, bool enable) +{ + struct aspeed_gpio *gpio = gpiochip_get_data(chip); + const struct aspeed_gpio_bank *bank; + unsigned long flags; + u32 val; + + bank = to_bank(offset); + + spin_lock_irqsave(&gpio->lock, flags); + val = readl(gpio->base + bank->tolerance_regs); + + if (enable) + val |= GPIO_BIT(offset); + else + val &= ~GPIO_BIT(offset); + + writel(val, gpio->base + bank->tolerance_regs); + spin_unlock_irqrestore(&gpio->lock, flags); + + return 0; +} + static int aspeed_gpio_request(struct gpio_chip *chip, unsigned int offset) { if (!have_gpio(gpiochip_get_data(chip), offset)) @@ -765,6 +798,8 @@ static int aspeed_gpio_set_config(struct gpio_chip *chip, unsigned int offset, param == PIN_CONFIG_DRIVE_OPEN_SOURCE) /* Return -ENOTSUPP to trigger emulation, as per datasheet */ return -ENOTSUPP; + else if (param == PIN_CONFIG_PERSIST_STATE) + return aspeed_gpio_reset_tolerance(chip, offset, arg); return -ENOTSUPP; }