From patchwork Sun Jul 10 15:03:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lino Sanfilippo X-Patchwork-Id: 589334 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 CF083C43334 for ; Sun, 10 Jul 2022 15:04:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229598AbiGJPEJ (ORCPT ); Sun, 10 Jul 2022 11:04:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57826 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229543AbiGJPED (ORCPT ); Sun, 10 Jul 2022 11:04:03 -0400 Received: from mout.gmx.net (mout.gmx.net [212.227.15.15]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 81DB4656C; Sun, 10 Jul 2022 08:03:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1657465410; bh=8FT0ij9jO2V6dVyym1DjOHi++3Z/BUIKRaGKBNPBHZ8=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:In-Reply-To:References; b=j1NDK0qIJSgyoyQmV338pTIYOvQ6MoHZmvrGTE4EmRaq0EK0k6hXp0LR16Bu2iYFa NlRG+VpcQyy9QdG0yM+yAxjerCCYcqE2VR6f2HxcHq5zflGY7Dmpc32tCuR2Eropbv 9JQlLewzSIKnl8HgsfkLjQr5N/+mU7Q2P5zA5+RE= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Received: from localhost.localdomain ([46.223.3.243]) by mail.gmx.net (mrgmx004 [212.227.17.190]) with ESMTPSA (Nemesis) id 1N33Il-1nRUPH1Vxl-013O1Y; Sun, 10 Jul 2022 17:03:30 +0200 From: Lino Sanfilippo To: gregkh@linuxfoundation.org, jirislaby@kernel.org Cc: ilpo.jarvinen@linux.intel.com, robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org, andriy.shevchenko@linux.intel.com, vz@mleia.com, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, linux-serial@vger.kernel.org, linux-kernel@vger.kernel.org, lukas@wunner.de, p.rosenberger@kunbus.com, Lino Sanfilippo Subject: [PATCH v3 3/8] serial: core, 8250: set RS485 termination gpio in serial core Date: Sun, 10 Jul 2022 17:03:17 +0200 Message-Id: <20220710150322.2846170-4-LinoSanfilippo@gmx.de> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220710150322.2846170-1-LinoSanfilippo@gmx.de> References: <20220710150322.2846170-1-LinoSanfilippo@gmx.de> MIME-Version: 1.0 X-Provags-ID: V03:K1:qrz8l9nuTB/MvdivY3E4Gq67uW4qo5owht5uptPokpBMWVbqBdB gu79o5AcnqycxmjkNIKQ7S4LsmUbyZg0DR1jcf8ASWKU4xy2r0Z34N37xrO1xtwNHVtNCpO 5/3cWtbSvTusl5UvUGeJ2dq/6MjrMTFxul+nqgyegdAI5EhLQDhe8TKqXlGlM34GADCSjOX 59bKhFgdWc150BauLLcWQ== X-UI-Out-Filterresults: notjunk:1;V03:K0:99l66P87yug=:6330KW07YlG0wPh3HArFB7 ngV5mGsIwIlZWOuQ5XA8irS1dxOvPVwy4p4conwKbGjEnGU9jns8Yj4PsCcHjgvdSXayXGZRc nxm5ih3cQ1AYXJ3C7VaU2SiBEPb9hgZxU+O/gbHJMRlPeyE2zKI0iEciSpEpM8DQAG9YzwvLk xj4MOnU98TII/DFm4CrxkjJVYQACaAh4OvF5ypzds1x1KzI7O5516h9L7Z07Uo58flqy7gff7 rJx20LCmauC1CfNo5NDKCkJj67JS189scZ8lmrwaW6hsRAoBGzLHwq4IfbLGvZH8BprP8Czjr scka1uAaYtagPpgKsDSEThMKcEp05iDMtI1zcVaotDV+Wdthmb96MmxUxxB9ZAdr41eHFjuz8 xui4L9YDcE2oWDazNYJs0YDDI0RH5ZipHVbFPqmJJ3EtzvxNh6oy0G0TBDoMS3GSmGuptcR4d qaky/u15vTKjmFven38P16tlFp3dKWnjo/XArpMX3goCVyKa/It9JO7kNvG089mxAsDQXvGxP E8fKdK/76OeHW2stu3WI6oFKzym4kTSXVT2l+CbzWaVtMwTkNFhQhHzBzcZSYCzb7jdU6auQ/ 5b7WmZp/FpM62xFuGgaeCM8hvrGATdzxj0l97EZwpOwazIRqAAWwiBckAkwR6peW9VLsB2tDD M7smwAKv4OFbNh/exRard+fOzanyNdda5jbJru714p3KAmOngnGZwWARgS+pVBBCd9ZKYOIw9 TT4p3PckA2Sfpc5GHFEjdaUt0D1AsXNgtDOZyAGW/Ra4puDZ4LM9EQZmF7LgEMxP5R8rf/DYZ io2LgEqrXKGp4GYzwzz3sVPVjmzpuWWyhfLTmUUVL+5oAIrJwj/V2HAHJmRmH7D4qz8nrnEpO cd+lQOLL7+0QNxpfAH0CDzC5O/MAy97u4t2r2Pnf2mBb6Xp+eYsk4J0gipTGQsr0mvhvPlO8O 5l2p++rKCCshWslRnYXXTgWi75y+hrjgug9Ln6FI2lIChqYzZ5SB+uhHMVGHjgLjEL/2zuUEo soqIFti6fPLEvnSG/NXFWF/f//kThn142/mVisrYHANovIOXkzZW5Bt7RmPV7kEVksjw52oHC uNPDYG+bTFlGSJwHemoOqdreYjEC/i/QfRyZzVdrtcemMNacv0wpXpvvA== Precedence: bulk List-ID: X-Mailing-List: linux-serial@vger.kernel.org From: Lino Sanfilippo In serial8250_em485_config() the termination GPIO is set with the uart_port spinlock held. This is an issue if setting the GPIO line can sleep (e.g. since the concerning GPIO expander is connected via SPI or I2C). Fix this by setting the termination line outside of the uart_port spinlock in the serial core and using gpiod_set_value_cansleep() which instead of gpiod_set_value() allows it to sleep. Beside fixing the termination GPIO line setting for the 8250 driver this change also makes setting the termination GPIO generic for all UART drivers. Signed-off-by: Lino Sanfilippo Reported-by: kernel test robot --- drivers/tty/serial/8250/8250_port.c | 3 --- drivers/tty/serial/serial_core.c | 12 ++++++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index ed2a606f2da7..72252d956f17 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -676,9 +676,6 @@ int serial8250_em485_config(struct uart_port *port, struct ktermios *termios, rs485->flags &= ~SER_RS485_RTS_AFTER_SEND; } - gpiod_set_value(port->rs485_term_gpio, - rs485->flags & SER_RS485_TERMINATE_BUS); - /* * Both serial8250_em485_init() and serial8250_em485_destroy() * are idempotent. diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c index 1db44cde76f6..612a97788341 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c @@ -1358,12 +1358,23 @@ static void uart_sanitize_serial_rs485(struct uart_port *port, struct serial_rs4 memset(rs485->padding1, 0, sizeof(rs485->padding1)); } +static void uart_set_rs485_termination(struct uart_port *port, + const struct serial_rs485 *rs485) +{ + if (!rs485->flags & SER_RS485_ENABLED) + return; + + gpiod_set_value_cansleep(port->rs485_term_gpio, + !!(rs485->flags & SER_RS485_TERMINATE_BUS)); +} + int uart_rs485_config(struct uart_port *port) { struct serial_rs485 *rs485 = &port->rs485; int ret; uart_sanitize_serial_rs485(port, rs485); + uart_set_rs485_termination(port, rs485); ret = port->rs485_config(port, NULL, rs485); if (ret) @@ -1406,6 +1417,7 @@ static int uart_set_rs485_config(struct tty_struct *tty, struct uart_port *port, if (ret) return ret; uart_sanitize_serial_rs485(port, &rs485); + uart_set_rs485_termination(port, &rs485); spin_lock_irqsave(&port->lock, flags); ret = port->rs485_config(port, &tty->termios, &rs485);