12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 2affddff6SRussell Currey /* 3affddff6SRussell Currey * kmsg dumper that ensures the OPAL console fully flushes panic messages 4affddff6SRussell Currey * 5affddff6SRussell Currey * Author: Russell Currey <ruscur@russell.cc> 6affddff6SRussell Currey * 7affddff6SRussell Currey * Copyright 2015 IBM Corporation. 8affddff6SRussell Currey */ 9affddff6SRussell Currey 10affddff6SRussell Currey #include <linux/kmsg_dump.h> 11affddff6SRussell Currey 12affddff6SRussell Currey #include <asm/opal.h> 13affddff6SRussell Currey #include <asm/opal-api.h> 14affddff6SRussell Currey 15affddff6SRussell Currey /* 16affddff6SRussell Currey * Console output is controlled by OPAL firmware. The kernel regularly calls 17affddff6SRussell Currey * OPAL_POLL_EVENTS, which flushes some console output. In a panic state, 18affddff6SRussell Currey * however, the kernel no longer calls OPAL_POLL_EVENTS and the panic message 19affddff6SRussell Currey * may not be completely printed. This function does not actually dump the 20affddff6SRussell Currey * message, it just ensures that OPAL completely flushes the console buffer. 21affddff6SRussell Currey */ kmsg_dump_opal_console_flush(struct kmsg_dumper * dumper,enum kmsg_dump_reason reason)22d2a2262eSNicholas Pigginstatic void kmsg_dump_opal_console_flush(struct kmsg_dumper *dumper, 23affddff6SRussell Currey enum kmsg_dump_reason reason) 24affddff6SRussell Currey { 25affddff6SRussell Currey /* 26affddff6SRussell Currey * Outside of a panic context the pollers will continue to run, 27affddff6SRussell Currey * so we don't need to do any special flushing. 28affddff6SRussell Currey */ 29affddff6SRussell Currey if (reason != KMSG_DUMP_PANIC) 30affddff6SRussell Currey return; 31affddff6SRussell Currey 32d2a2262eSNicholas Piggin opal_flush_console(0); 33affddff6SRussell Currey } 34affddff6SRussell Currey 35affddff6SRussell Currey static struct kmsg_dumper opal_kmsg_dumper = { 36d2a2262eSNicholas Piggin .dump = kmsg_dump_opal_console_flush 37affddff6SRussell Currey }; 38affddff6SRussell Currey opal_kmsg_init(void)39affddff6SRussell Curreyvoid __init opal_kmsg_init(void) 40affddff6SRussell Currey { 41affddff6SRussell Currey int rc; 42affddff6SRussell Currey 43affddff6SRussell Currey /* Add our dumper to the list */ 44affddff6SRussell Currey rc = kmsg_dump_register(&opal_kmsg_dumper); 45affddff6SRussell Currey if (rc != 0) 46affddff6SRussell Currey pr_err("opal: kmsg_dump_register failed; returned %d\n", rc); 47affddff6SRussell Currey } 48