18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * kmsg dumper that ensures the OPAL console fully flushes panic messages 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Author: Russell Currey <ruscur@russell.cc> 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Copyright 2015 IBM Corporation. 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/kmsg_dump.h> 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#include <asm/opal.h> 138c2ecf20Sopenharmony_ci#include <asm/opal-api.h> 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci/* 168c2ecf20Sopenharmony_ci * Console output is controlled by OPAL firmware. The kernel regularly calls 178c2ecf20Sopenharmony_ci * OPAL_POLL_EVENTS, which flushes some console output. In a panic state, 188c2ecf20Sopenharmony_ci * however, the kernel no longer calls OPAL_POLL_EVENTS and the panic message 198c2ecf20Sopenharmony_ci * may not be completely printed. This function does not actually dump the 208c2ecf20Sopenharmony_ci * message, it just ensures that OPAL completely flushes the console buffer. 218c2ecf20Sopenharmony_ci */ 228c2ecf20Sopenharmony_cistatic void kmsg_dump_opal_console_flush(struct kmsg_dumper *dumper, 238c2ecf20Sopenharmony_ci enum kmsg_dump_reason reason) 248c2ecf20Sopenharmony_ci{ 258c2ecf20Sopenharmony_ci /* 268c2ecf20Sopenharmony_ci * Outside of a panic context the pollers will continue to run, 278c2ecf20Sopenharmony_ci * so we don't need to do any special flushing. 288c2ecf20Sopenharmony_ci */ 298c2ecf20Sopenharmony_ci if (reason != KMSG_DUMP_PANIC) 308c2ecf20Sopenharmony_ci return; 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci opal_flush_console(0); 338c2ecf20Sopenharmony_ci} 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_cistatic struct kmsg_dumper opal_kmsg_dumper = { 368c2ecf20Sopenharmony_ci .dump = kmsg_dump_opal_console_flush 378c2ecf20Sopenharmony_ci}; 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_civoid __init opal_kmsg_init(void) 408c2ecf20Sopenharmony_ci{ 418c2ecf20Sopenharmony_ci int rc; 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci /* Add our dumper to the list */ 448c2ecf20Sopenharmony_ci rc = kmsg_dump_register(&opal_kmsg_dumper); 458c2ecf20Sopenharmony_ci if (rc != 0) 468c2ecf20Sopenharmony_ci pr_err("opal: kmsg_dump_register failed; returned %d\n", rc); 478c2ecf20Sopenharmony_ci} 48