From patchwork Thu Mar 17 13:47:28 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Geert Uytterhoeven X-Patchwork-Id: 8611161 X-Patchwork-Delegate: geert@linux-m68k.org Return-Path: X-Original-To: patchwork-linux-sh@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id BBB93C0553 for ; Thu, 17 Mar 2016 13:47:49 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 72D42202EC for ; Thu, 17 Mar 2016 13:47:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 76E5A2034A for ; Thu, 17 Mar 2016 13:47:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S936081AbcCQNrh (ORCPT ); Thu, 17 Mar 2016 09:47:37 -0400 Received: from xavier.telenet-ops.be ([195.130.132.52]:38948 "EHLO xavier.telenet-ops.be" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S936132AbcCQNrd (ORCPT ); Thu, 17 Mar 2016 09:47:33 -0400 Received: from ayla.of.borg ([84.195.106.123]) by xavier.telenet-ops.be with bizsmtp id X1nU1s00J2fm56U011nUmV; Thu, 17 Mar 2016 14:47:29 +0100 Received: from ramsan.of.borg ([192.168.97.29] helo=ramsan) by ayla.of.borg with esmtp (Exim 4.82) (envelope-from ) id 1agYGu-0001Bz-GJ; Thu, 17 Mar 2016 14:47:28 +0100 Received: from geert by ramsan with local (Exim 4.82) (envelope-from ) id 1agYGx-0003Dl-3f; Thu, 17 Mar 2016 14:47:31 +0100 From: Geert Uytterhoeven To: Greg Kroah-Hartman , Jiri Slaby , Peter Hurley , Magnus Damm Cc: Laurent Pinchart , Yoshinori Sato , linux-serial@vger.kernel.org, linux-renesas-soc@vger.kernel.org, linux-sh@vger.kernel.org, Geert Uytterhoeven Subject: [PATCH/RFC 4/5] serial: sh-sci: Add support for GPIO-controlled modem lines Date: Thu, 17 Mar 2016 14:47:28 +0100 Message-Id: <1458222449-12324-5-git-send-email-geert+renesas@glider.be> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1458222449-12324-1-git-send-email-geert+renesas@glider.be> References: <1458222449-12324-1-git-send-email-geert+renesas@glider.be> Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Enhance the Renesas SCI UART driver to add support for GPIO-controlled modem lines (CTS, DSR, DCD, RNG, RTS, DTR, OUT1, and OUT2), using the SERIAL_MCTRL_GPIO helpers. GPIO-controlled modem lines can be used where dedicated modem lines are not available. Signed-off-by: Geert Uytterhoeven --- Testing for regressions on platforms without DT and/or GPIOLIB support (SuperH) would be appreciated. Compile-tested on ecovec24_defconfig(GPIOLIB=y) and se7780_defconfig (GPIOLIB=n). --- drivers/tty/serial/Kconfig | 1 + drivers/tty/serial/sh-sci.c | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 13d4ed6caac4a78b..ebf91bbfdf0f999d 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -735,6 +735,7 @@ config SERIAL_SH_SCI tristate "SuperH SCI(F) serial port support" depends on SUPERH || ARCH_RENESAS || H8300 || COMPILE_TEST select SERIAL_CORE + select SERIAL_MCTRL_GPIO if GPIOLIB config SERIAL_SH_SCI_NR_UARTS int "Maximum number of SCI(F) serial ports" diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 135f836642ab1c5a..6897100ed5197df3 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -57,6 +57,7 @@ #include #endif +#include "serial_mctrl_gpio.h" #include "sh-sci.h" /* Offsets into the sci_port->irqs array */ @@ -111,6 +112,7 @@ struct sci_port { unsigned int error_clear; unsigned int sampling_rate_mask; resource_size_t reg_size; + struct mctrl_gpios *gpios; /* Break timer */ struct timer_list break_timer; @@ -1829,15 +1831,36 @@ static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl) serial_port_in(port, SCFCR) | SCFCR_LOOP); } + + mctrl_gpio_set(to_sci_port(port)->gpios, mctrl); } static unsigned int sci_get_mctrl(struct uart_port *port) { + unsigned int mctrl = 0; + + mctrl_gpio_get(to_sci_port(port)->gpios, &mctrl); + /* * CTS/RTS is handled in hardware when supported, while nothing * else is wired up. Keep it simple and simply assert CTS/DSR/CAR. */ - return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; + if (IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(to_sci_port(port)->gpios, + UART_GPIO_CTS))) + mctrl |= TIOCM_CTS; + if (IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(to_sci_port(port)->gpios, + UART_GPIO_DSR))) + mctrl |= TIOCM_DSR; + if (IS_ERR_OR_NULL(mctrl_gpio_to_gpiod(to_sci_port(port)->gpios, + UART_GPIO_CAR))) + mctrl |= TIOCM_CAR; + + return mctrl; +} + +static void sci_enable_ms(struct uart_port *port) +{ + mctrl_gpio_enable_ms(to_sci_port(port)->gpios); } static void sci_break_ctl(struct uart_port *port, int break_state) @@ -1899,6 +1922,8 @@ static void sci_shutdown(struct uart_port *port) dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); + mctrl_gpio_disable_ms(to_sci_port(port)->gpios); + spin_lock_irqsave(&port->lock, flags); sci_stop_rx(port); sci_stop_tx(port); @@ -2300,6 +2325,9 @@ done: sci_start_rx(port); sci_port_disable(s); + + if (UART_ENABLE_MS(port, termios->c_cflag)) + sci_enable_ms(port); } static void sci_pm(struct uart_port *port, unsigned int state, @@ -2425,6 +2453,7 @@ static struct uart_ops sci_uart_ops = { .start_tx = sci_start_tx, .stop_tx = sci_stop_tx, .stop_rx = sci_stop_rx, + .enable_ms = sci_enable_ms, .break_ctl = sci_break_ctl, .startup = sci_startup, .shutdown = sci_shutdown, @@ -2912,6 +2941,10 @@ static int sci_probe_single(struct platform_device *dev, if (ret) return ret; + sciport->gpios = mctrl_gpio_init(&sciport->port, 0); + if (IS_ERR(sciport->gpios) && PTR_ERR(sciport->gpios) != -ENOSYS) + return PTR_ERR(sciport->gpios); + ret = uart_add_one_port(&sci_uart_driver, &sciport->port); if (ret) { sci_cleanup_single(sciport);