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