From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 34BA8C83F3F for ; Mon, 4 Sep 2023 18:34:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345463AbjIDSed (ORCPT ); Mon, 4 Sep 2023 14:34:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38066 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347626AbjIDSe1 (ORCPT ); Mon, 4 Sep 2023 14:34:27 -0400 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 231E3CCB for ; Mon, 4 Sep 2023 11:34:24 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id D84FAB80EF4 for ; Mon, 4 Sep 2023 18:34:22 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4D64BC433C9; Mon, 4 Sep 2023 18:34:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1693852461; bh=Oar6EGpn+1vy520vivIstBo/BiGHT9OAIkhOyCZpmBE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZvxH7me8c4IBHFZDACcU8dPTji11mzlV0qZvvhVV/cibKFmSSRt/XoxHctQ2LZtRg YefLIW2Msq4QZdSQLtG5dlktJlrCJeWmV6vMOVc+g8X2kXHZaXi4nBUT8FQywwAGvZ 243BBpFh8AUWG6r0mVhc3RNVx/cGgiTAZH3ntZDg= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Hugo Villeneuve , Lech Perczak Subject: [PATCH 6.4 25/32] serial: sc16is7xx: fix bug when first setting GPIO direction Date: Mon, 4 Sep 2023 19:30:23 +0100 Message-ID: <20230904182949.047459450@linuxfoundation.org> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20230904182947.899158313@linuxfoundation.org> References: <20230904182947.899158313@linuxfoundation.org> User-Agent: quilt/0.67 X-stable: review X-Patchwork-Hint: ignore MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org 6.4-stable review patch. If anyone has any objections, please let me know. ------------------ From: Hugo Villeneuve commit 9baeea723c0fb9c3ba9a336369f758ed9bc6831d upstream. When configuring a pin as an output pin with a value of logic 0, we end up as having a value of logic 1 on the output pin. Setting a logic 0 a second time (or more) after that will correctly output a logic 0 on the output pin. By default, all GPIO pins are configured as inputs. When we enter sc16is7xx_gpio_direction_output() for the first time, we first set the desired value in IOSTATE, and then we configure the pin as an output. The datasheet states that writing to IOSTATE register will trigger a transfer of the value to the I/O pin configured as output, so if the pin is configured as an input, nothing will be transferred. Therefore, set the direction first in IODIR, and then set the desired value in IOSTATE. This is what is done in NXP application note AN10587. Fixes: dfeae619d781 ("serial: sc16is7xx") Cc: stable@vger.kernel.org Signed-off-by: Hugo Villeneuve Reviewed-by: Lech Perczak Tested-by: Lech Perczak Link: https://lore.kernel.org/r/20230807214556.540627-6-hugo@hugovil.com Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/sc16is7xx.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c @@ -1342,9 +1342,18 @@ static int sc16is7xx_gpio_direction_outp state |= BIT(offset); else state &= ~BIT(offset); - sc16is7xx_port_write(port, SC16IS7XX_IOSTATE_REG, state); + + /* + * If we write IOSTATE first, and then IODIR, the output value is not + * transferred to the corresponding I/O pin. + * The datasheet states that each register bit will be transferred to + * the corresponding I/O pin programmed as output when writing to + * IOSTATE. Therefore, configure direction first with IODIR, and then + * set value after with IOSTATE. + */ sc16is7xx_port_update(port, SC16IS7XX_IODIR_REG, BIT(offset), BIT(offset)); + sc16is7xx_port_write(port, SC16IS7XX_IOSTATE_REG, state); return 0; }