From patchwork Wed Jan 9 19:35:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Goldschmidt X-Patchwork-Id: 1022600 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="NPhlLZeE"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 43ZfVq190Nz9sLt for ; Thu, 10 Jan 2019 06:35:46 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 9AC14C22032; Wed, 9 Jan 2019 19:35:43 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id ED7CFC21F67; Wed, 9 Jan 2019 19:35:39 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 9C98AC21F77; Wed, 9 Jan 2019 19:35:38 +0000 (UTC) Received: from mail-wm1-f68.google.com (mail-wm1-f68.google.com [209.85.128.68]) by lists.denx.de (Postfix) with ESMTPS id 7D6DDC21F67 for ; Wed, 9 Jan 2019 19:35:37 +0000 (UTC) Received: by mail-wm1-f68.google.com with SMTP id m22so9630020wml.3 for ; Wed, 09 Jan 2019 11:35:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=+JSxW1cZromxPRI2KYN1EAkWTypiMG9QVI0oazOYVeU=; b=NPhlLZeElDQPCuWthr1HGytoogV59kQuH/zPr5BRbmK5tBO8Xqse8qf4fjmRwenDb4 FNqdCeqtHjDT7v9SWdd7p6gQ6mSLk6hYtFKV29UuqsAjI3bJVGw0frGrFrDWLD0uym2v boZgj6qkEakK4McOrwdLIdeFn8vt+bODZzmK5iam6A9UF8G6Xn2rJGUKAbBf2+YR4yUt qzpQG0UdJSJjjIA4k8/c+K/JVjZkUOfdKIZjUMI65Wntu1eYJx/oV/5nlhWM+ICKSTiV FVTnNJ63Sn786aagGQ2KeyM00EZXMlvzZEGmDWFhvmwf9npV+KXh4gJvkmKKhHWWDkqE 2AnA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=+JSxW1cZromxPRI2KYN1EAkWTypiMG9QVI0oazOYVeU=; b=tcqA6WbKxq41FhbLxWwDJ/3gotbAgJ0nFMrg/qH91JUatg6SWtO08LDkS7stI6S0z3 JVos+G2RMGFul/QccREE9Rcsok2mSC8U2QYKJgN5U0bMQUt9cXlToFFNCIMVAzc0e4BP 9hOAQxjGZOnGHZZ16CyjUaZjkQ1iKkmlwNyJayg1CNRkA4UBDwPJfmm+MzA67XX6e+dd mOQf0kXpEU4w85GWV2rDc0aL3FXjLoXodIhd24FEDEkWurAYxrijWIF2zNzCZKjerJ65 PpShiAd0hejiY5Y7UrExFDRuEWFlRLw9xHZ3ygYNEPJKxa/c61yPkDxKqitqv05mZQVC TlNg== X-Gm-Message-State: AJcUukekWv6/QobKqaHmhBJkPI6Z9gaNs894jsf1aNFpTMivdQo0Oxux ifZHD/EFf/eCIcE25NOvn40= X-Google-Smtp-Source: ALg8bN59QrUoEwCjrF1z9Q9161Bh/qCVL5wwO4AjEHD6whw4Vpk/7eJkZhfC5WGXaTgKKcf6Ivh9GQ== X-Received: by 2002:a1c:26c1:: with SMTP id m184mr6618999wmm.25.1547062537051; Wed, 09 Jan 2019 11:35:37 -0800 (PST) Received: from ubuntu.home ([2a02:8071:6a3:700:8c22:ee0c:efc8:ed86]) by smtp.gmail.com with ESMTPSA id c65sm13777278wma.24.2019.01.09.11.35.35 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 09 Jan 2019 11:35:36 -0800 (PST) From: Simon Goldschmidt To: Tom Rini , u-boot@lists.denx.de Date: Wed, 9 Jan 2019 20:35:31 +0100 Message-Id: <20190109193531.12156-1-simon.k.r.goldschmidt@gmail.com> X-Mailer: git-send-email 2.17.1 Cc: Andy Shevchenko , Alexey Brodkin , Ryder Lee , Alexander Graf Subject: [U-Boot] [PATCH] serial: ns16550: fix debug uart putc called before init X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" If _debug_uart_putc() is called before _debug_uart_init(), the ns16550 debug uart driver hangs in a tight loop waiting for the tx FIFO to get empty. As this can happen via a printf sneaking in before the port calls debug_uart_init(), introduce a config option to ignore characters before the debug uart is initialized. This is done by reading the baudrate divisor and aborting if is zero. The Kconfig option is required as reading the baudrate divisor does not seem to work for all ns16500 compatibles (which is why the last attempt on this has been reverted in 1a67969a99). Tested on socfpga_cyclone5_socrates. Signed-off-by: Simon Goldschmidt Reviewed-by: Simon Glass --- drivers/serial/Kconfig | 12 ++++++++++++ drivers/serial/ns16550.c | 20 ++++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index b7ff2960ab..8709bf69c0 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -446,6 +446,18 @@ config DEBUG_UART_SKIP_INIT Select this if the UART you want to use for debug output is already initialized by the time U-Boot starts its execution. +config DEBUG_UART_NS16550_CHECK_ENABLED + bool "Check if UART is enabled on output" + depends on DEBUG_UART + depends on DEBUG_UART_NS16550 + help + Select this if puts()/putc() might be called before the debug UART + has been initialized. If this is disabled, putc() might sit in a + tight loop if it is called before debug_uart_init() has been called. + + Note that this does not work for every ns16550-compatible UART and + so has to be enabled carefully or you might notice lost characters. + config ALTERA_JTAG_UART bool "Altera JTAG UART support" depends on DM_SERIAL diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c index 560ca2ae34..6cf2be8f2b 100644 --- a/drivers/serial/ns16550.c +++ b/drivers/serial/ns16550.c @@ -272,12 +272,28 @@ static inline void _debug_uart_init(void) serial_dout(&com_port->lcr, UART_LCRVAL); } +static inline int NS16550_read_baud_divisor(struct NS16550 *com_port) +{ + int ret; + + serial_dout(&com_port->lcr, UART_LCR_BKSE | UART_LCRVAL); + ret = serial_din(&com_port->dll) & 0xff; + ret |= (serial_din(&com_port->dlm) & 0xff) << 8; + serial_dout(&com_port->lcr, UART_LCRVAL); + + return ret; +} + static inline void _debug_uart_putc(int ch) { struct NS16550 *com_port = (struct NS16550 *)CONFIG_DEBUG_UART_BASE; - while (!(serial_din(&com_port->lsr) & UART_LSR_THRE)) - ; + while (!(serial_din(&com_port->lsr) & UART_LSR_THRE)) { +#ifdef CONFIG_DEBUG_UART_NS16550_CHECK_ENABLED + if (!NS16550_read_baud_divisor(com_port)) + return; +#endif + } serial_dout(&com_port->thr, ch); }