From patchwork Thu Nov 3 12:57:58 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Burton X-Patchwork-Id: 690823 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3t8lTJ2lzrz9t0q for ; Fri, 4 Nov 2016 00:01:08 +1100 (AEDT) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3t8lTJ1jhbzDvZh for ; Fri, 4 Nov 2016 00:01:08 +1100 (AEDT) X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Received: from mailapp01.imgtec.com (mailapp01.imgtec.com [195.59.15.196]) by lists.ozlabs.org (Postfix) with ESMTP id 3t8lRy4zDzzDvQZ for ; Thu, 3 Nov 2016 23:59:58 +1100 (AEDT) Received: from HHMAIL01.hh.imgtec.org (unknown [10.100.10.19]) by Forcepoint Email with ESMTPS id 4D2C1DFF9CE38; Thu, 3 Nov 2016 12:59:52 +0000 (GMT) Received: from localhost (10.100.200.188) by HHMAIL01.hh.imgtec.org (10.100.10.21) with Microsoft SMTP Server (TLS) id 14.3.294.0; Thu, 3 Nov 2016 12:59:54 +0000 From: Paul Burton To: Larry Finger , Michael Ellerman , Sergey Senozhatsky Subject: [PATCH v3] console: use first console if stdout-path device doesn't appear Date: Thu, 3 Nov 2016 12:57:58 +0000 Message-ID: <20161103125758.3415-1-paul.burton@imgtec.com> X-Mailer: git-send-email 2.10.2 In-Reply-To: <2c67e39b-fc33-918a-774e-d9238e837c03@lwfinger.net> References: <2c67e39b-fc33-918a-774e-d9238e837c03@lwfinger.net> MIME-Version: 1.0 X-Originating-IP: [10.100.200.188] X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Petr Mladek , Paul Burton , linux-kernel@vger.kernel.org, Andreas Schwab , Tejun Heo , Andrew Morton , Borislav Petkov , linuxppc-dev@lists.ozlabs.org Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" If a device tree specified a preferred device for kernel console output via the stdout-path or linux,stdout-path chosen node properties there's no guarantee that it will have specified a device for which we have a driver. It may also be the case that we do have a driver but it doesn't call of_console_check() to register as a preferred console (eg. offb driver as used on powermac systems). In these cases try to ensure that we provide some console output by enabling the first usable registered console, which we keep track of with the of_fallback_console variable. Affected systems will enable their console later than they did prior to commit 05fd007e4629 ("console: don't prefer first registered if DT specifies stdout-path") but should otherwise produce the same output. Tested in QEMU with a PowerPC pseries_defconfig kernel. Signed-off-by: Paul Burton Fixes: 05fd007e4629 ("console: don't prefer first registered if DT specifies stdout-path") Reported-by: Andreas Schwab Reported-by: Larry Finger Reported-by: Michael Ellerman Cc: Andreas Schwab Cc: Andrew Morton Cc: Borislav Petkov Cc: Larry Finger Cc: Michael Ellerman Cc: Petr Mladek Cc: Sergey Senozhatsky Cc: Tejun Heo Cc: linux-kernel@vger.kernel.org Cc: linuxppc-dev@lists.ozlabs.org --- Changes in v3: - Be less invasive by simply calling register_console() again rather than splitting it. - Check for CON_CONSDEV on the first console driver rather than for CON_ENABLED on any. - Clean up the tracking of the fallback console. Changes in v2: - Split enable_console() out of register_console() & call in the fallback case. - Track the console we would have enabled as of_fallback_console. kernel/printk/printk.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index de08fc9..c86e6d0 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -260,10 +260,18 @@ void console_set_by_of(void) { of_specified_console = true; } + +static void clear_of_specified_console(void) +{ + of_specified_console = false; +} #else # define of_specified_console false +static void clear_of_specified_console(void) { } #endif +struct console *of_fallback_console; + /* Flag: console code may call schedule() */ static int console_may_schedule; @@ -2657,10 +2665,26 @@ void register_console(struct console *newcon) * didn't select a console we take the first one * that registers here. */ - if (preferred_console < 0 && !of_specified_console) { + if (preferred_console < 0) { if (newcon->index < 0) newcon->index = 0; - if (newcon->setup == NULL || + if (of_specified_console) { + /* + * The device tree stdout-path chosen node property was + * specified so we don't want to enable the first + * registered console just now in order to give the + * device indicated by stdout-path a chance to be + * registered first. Do however keep track of the + * first console we see so that we can fall back to + * using it if we don't see the desired device, either + * because stdout-path isn't valid, or because we have + * no driver for the device or our driver doesn't call + * of_console_check(). See printk_late_init() for this + * fallback. + */ + if (!of_fallback_console) + of_fallback_console = newcon; + } else if (newcon->setup == NULL || newcon->setup(newcon, NULL) == 0) { newcon->flags |= CON_ENABLED; if (newcon->device) { @@ -2844,6 +2868,22 @@ static int __init printk_late_init(void) { struct console *con; + if (of_specified_console && of_fallback_console && + (!console_drivers || !(console_drivers->flags & CON_CONSDEV))) { + /* + * The system has a device tree which specified stdout-path, + * but we haven't seen a console associated with the device + * specified by the stdout-path chosen node property. + * + * We do however know which console would have been used + * if stdout-path weren't specified at all, so in an attempt + * to provide some output we'll re-register that console + * pretending that we never saw stdout-path. + */ + clear_of_specified_console(); + register_console(of_fallback_console); + } + for_each_console(con) { if (!keep_bootcon && con->flags & CON_BOOT) { /*