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