1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Pvpanic Device Support 4 * 5 * Copyright (C) 2013 Fujitsu. 6 * Copyright (C) 2018 ZTE. 7 * Copyright (C) 2021 Oracle. 8 */ 9 10 #include <linux/io.h> 11 #include <linux/kernel.h> 12 #include <linux/kexec.h> 13 #include <linux/mod_devicetable.h> 14 #include <linux/module.h> 15 #include <linux/platform_device.h> 16 #include <linux/types.h> 17 18 #include <uapi/misc/pvpanic.h> 19 20 #include "pvpanic.h" 21 22 MODULE_AUTHOR("Mihai Carabas <mihai.carabas@oracle.com>"); 23 MODULE_DESCRIPTION("pvpanic device driver "); 24 MODULE_LICENSE("GPL"); 25 26 static void __iomem *base; 27 static unsigned int capability; 28 static unsigned int events; 29 30 static void 31 pvpanic_send_event(unsigned int event) 32 { 33 if (event & capability & events) 34 iowrite8(event, base); 35 } 36 37 static int 38 pvpanic_panic_notify(struct notifier_block *nb, unsigned long code, 39 void *unused) 40 { 41 unsigned int event = PVPANIC_PANICKED; 42 43 if (kexec_crash_loaded()) 44 event = PVPANIC_CRASH_LOADED; 45 46 pvpanic_send_event(event); 47 48 return NOTIFY_DONE; 49 } 50 51 static struct notifier_block pvpanic_panic_nb = { 52 .notifier_call = pvpanic_panic_notify, 53 .priority = 1, /* let this called before broken drm_fb_helper */ 54 }; 55 56 void pvpanic_probe(void __iomem *pbase, unsigned int dev_cap) 57 { 58 base = pbase; 59 capability = dev_cap; 60 events = capability; 61 62 if (capability) 63 atomic_notifier_chain_register(&panic_notifier_list, 64 &pvpanic_panic_nb); 65 } 66 EXPORT_SYMBOL_GPL(pvpanic_probe); 67 68 void pvpanic_remove(void) 69 { 70 if (capability) 71 atomic_notifier_chain_unregister(&panic_notifier_list, 72 &pvpanic_panic_nb); 73 base = NULL; 74 } 75 EXPORT_SYMBOL_GPL(pvpanic_remove); 76 77 void pvpanic_set_events(unsigned int dev_events) 78 { 79 events = dev_events; 80 } 81 EXPORT_SYMBOL_GPL(pvpanic_set_events); 82