[S390] console flush on panic / reboot
The s390 console drivers use the unblank callback of the console
structure to flush the console buffer. In case of a panic or a
reboot the CPU doing the callback can block on the console i/o.
The other CPUs in the system continue to work. For panic this is
not a good idea.
Replace the unblank callback with proper panic/reboot notifier.
These get called after all but one CPU have been stopped.
Signed-off-by: Holger Smolinski <Holger.Smolinski@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c
index 3c07974..d028d2e 100644
--- a/drivers/s390/char/con3270.c
+++ b/drivers/s390/char/con3270.c
@@ -15,6 +15,7 @@
#include <linux/list.h>
#include <linux/types.h>
#include <linux/err.h>
+#include <linux/reboot.h>
#include <asm/ccwdev.h>
#include <asm/cio.h>
@@ -528,11 +529,11 @@
}
/*
- * panic() calls console_unblank before the system enters a
- * disabled, endless loop.
+ * panic() calls con3270_flush through a panic_notifier
+ * before the system enters a disabled, endless loop.
*/
static void
-con3270_unblank(void)
+con3270_flush(void)
{
struct con3270 *cp;
unsigned long flags;
@@ -554,6 +555,23 @@
spin_unlock_irqrestore(&cp->view.lock, flags);
}
+static int con3270_notify(struct notifier_block *self,
+ unsigned long event, void *data)
+{
+ con3270_flush();
+ return NOTIFY_OK;
+}
+
+static struct notifier_block on_panic_nb = {
+ .notifier_call = con3270_notify,
+ .priority = 0,
+};
+
+static struct notifier_block on_reboot_nb = {
+ .notifier_call = con3270_notify,
+ .priority = 0,
+};
+
/*
* The console structure for the 3270 console
*/
@@ -561,7 +579,6 @@
.name = "tty3270",
.write = con3270_write,
.device = con3270_device,
- .unblank = con3270_unblank,
.flags = CON_PRINTBUFFER,
};
@@ -623,6 +640,8 @@
condev->cline->len = 0;
con3270_create_status(condev);
condev->input = alloc_string(&condev->freemem, 80);
+ atomic_notifier_chain_register(&panic_notifier_list, &on_panic_nb);
+ register_reboot_notifier(&on_reboot_nb);
register_console(&con3270);
return 0;
}