aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Burton <paul.burton@imgtec.com>2016-10-07 20:03:15 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-10-07 21:46:30 -0400
commit05fd007e46296afb24d15c7d589d535e5a5b9d5c (patch)
tree281299e8ad44d78a2215f54c5dda0272b0c277bf
parent81243eacfa400f5f7b89f4c2323d0de9982bb0fb (diff)
console: don't prefer first registered if DT specifies stdout-path
If a device tree specifies a preferred device for kernel console output via the stdout-path or linux,stdout-path chosen node properties or the stdout alias then the kernel ought to honor it & output the kernel console to that device. As it stands, this isn't the case. Whilst we parse the stdout-path properties & set an of_stdout variable from of_alias_scan(), and use that from of_console_check() to determine whether to add a console device as a preferred console whilst registering it, we also prefer the first registered console if no other has been selected at the time of its registration. This means that if a console other than the one the device tree selects via stdout-path is registered first, we will switch to using it & when the stdout-path console is later registered the call to add_preferred_console() via of_console_check() is too late to do anything useful. In practice this seems to mean that we switch to the dummy console device fairly early & see no further console output: Console: colour dummy device 80x25 console [tty0] enabled bootconsole [ns16550a0] disabled Fix this by not automatically preferring the first registered console if one is specified by the device tree. This allows consoles to be registered but not enabled, and once the driver for the console selected by stdout-path calls of_console_check() the driver will be added to the list of preferred consoles before any other console has been enabled. When that console is then registered via register_console() it will be enabled as expected. Link: http://lkml.kernel.org/r/20160809151937.26118-1-paul.burton@imgtec.com Signed-off-by: Paul Burton <paul.burton@imgtec.com> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: Paul Burton <paul.burton@imgtec.com> Cc: Tejun Heo <tj@kernel.org> Cc: Sergey Senozhatsky <sergey.senozhatsky@gmail.com> Cc: Jiri Slaby <jslaby@suse.cz> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: Ivan Delalande <colona@arista.com> Cc: Thierry Reding <treding@nvidia.com> Cc: Borislav Petkov <bp@suse.de> Cc: Jan Kara <jack@suse.com> Cc: Petr Mladek <pmladek@suse.com> Cc: Joe Perches <joe@perches.com> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Rob Herring <robh+dt@kernel.org> Cc: Frank Rowand <frowand.list@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/of/base.c2
-rw-r--r--include/linux/console.h6
-rw-r--r--kernel/printk/printk.c13
3 files changed, 20 insertions, 1 deletions
diff --git a/drivers/of/base.c b/drivers/of/base.c
index a0bccb54a9bd..d687e6de24a0 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -2077,6 +2077,8 @@ void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
2077 name = of_get_property(of_aliases, "stdout", NULL); 2077 name = of_get_property(of_aliases, "stdout", NULL);
2078 if (name) 2078 if (name)
2079 of_stdout = of_find_node_opts_by_path(name, &of_stdout_options); 2079 of_stdout = of_find_node_opts_by_path(name, &of_stdout_options);
2080 if (of_stdout)
2081 console_set_by_of();
2080 } 2082 }
2081 2083
2082 if (!of_aliases) 2084 if (!of_aliases)
diff --git a/include/linux/console.h b/include/linux/console.h
index d530c4627e54..3672809234a7 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -173,6 +173,12 @@ static inline void console_sysfs_notify(void)
173#endif 173#endif
174extern bool console_suspend_enabled; 174extern bool console_suspend_enabled;
175 175
176#ifdef CONFIG_OF
177extern void console_set_by_of(void);
178#else
179static inline void console_set_by_of(void) {}
180#endif
181
176/* Suspend and resume console messages over PM events */ 182/* Suspend and resume console messages over PM events */
177extern void suspend_console(void); 183extern void suspend_console(void);
178extern void resume_console(void); 184extern void resume_console(void);
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index eea6dbc2d8cf..8019cc0d3a73 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -253,6 +253,17 @@ static int preferred_console = -1;
253int console_set_on_cmdline; 253int console_set_on_cmdline;
254EXPORT_SYMBOL(console_set_on_cmdline); 254EXPORT_SYMBOL(console_set_on_cmdline);
255 255
256#ifdef CONFIG_OF
257static bool of_specified_console;
258
259void console_set_by_of(void)
260{
261 of_specified_console = true;
262}
263#else
264# define of_specified_console false
265#endif
266
256/* Flag: console code may call schedule() */ 267/* Flag: console code may call schedule() */
257static int console_may_schedule; 268static int console_may_schedule;
258 269
@@ -2647,7 +2658,7 @@ void register_console(struct console *newcon)
2647 * didn't select a console we take the first one 2658 * didn't select a console we take the first one
2648 * that registers here. 2659 * that registers here.
2649 */ 2660 */
2650 if (preferred_console < 0) { 2661 if (preferred_console < 0 && !of_specified_console) {
2651 if (newcon->index < 0) 2662 if (newcon->index < 0)
2652 newcon->index = 0; 2663 newcon->index = 0;
2653 if (newcon->setup == NULL || 2664 if (newcon->setup == NULL ||