aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform
diff options
context:
space:
mode:
authorHu Tao <hutao@cn.fujitsu.com>2013-05-07 23:15:32 -0400
committerMatthew Garrett <matthew.garrett@nebula.com>2013-05-08 19:59:52 -0400
commit8b10acd74cdad9063c7a63468e31759d9ac877d9 (patch)
tree5725bbe99b4fe8393486bd7023c4313e8f2f2963 /drivers/platform
parenta849e0024a84480c7be85e3b723610e14042751b (diff)
pvpanic: pvpanic device driver
pvpanic device is a qemu simulated device through which guest panic event is sent to host. Signed-off-by: Hu Tao <hutao@cn.fujitsu.com> Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com>
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/x86/Kconfig8
-rw-r--r--drivers/platform/x86/Makefile2
-rw-r--r--drivers/platform/x86/pvpanic.c124
3 files changed, 134 insertions, 0 deletions
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 3338437b559b..85772616efbf 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -781,4 +781,12 @@ config APPLE_GMUX
781 graphics as well as the backlight. Currently only backlight 781 graphics as well as the backlight. Currently only backlight
782 control is supported by the driver. 782 control is supported by the driver.
783 783
784config PVPANIC
785 tristate "pvpanic device support"
786 depends on ACPI
787 ---help---
788 This driver provides support for the pvpanic device. pvpanic is
789 a paravirtualized device provided by QEMU; it lets a virtual machine
790 (guest) communicate panic events to the host.
791
784endif # X86_PLATFORM_DEVICES 792endif # X86_PLATFORM_DEVICES
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index ace2b38942fe..ef0ec746f78c 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -51,3 +51,5 @@ obj-$(CONFIG_INTEL_OAKTRAIL) += intel_oaktrail.o
51obj-$(CONFIG_SAMSUNG_Q10) += samsung-q10.o 51obj-$(CONFIG_SAMSUNG_Q10) += samsung-q10.o
52obj-$(CONFIG_APPLE_GMUX) += apple-gmux.o 52obj-$(CONFIG_APPLE_GMUX) += apple-gmux.o
53obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o 53obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o
54
55obj-$(CONFIG_PVPANIC) += pvpanic.o
diff --git a/drivers/platform/x86/pvpanic.c b/drivers/platform/x86/pvpanic.c
new file mode 100644
index 000000000000..47ae0c47d4b5
--- /dev/null
+++ b/drivers/platform/x86/pvpanic.c
@@ -0,0 +1,124 @@
1/*
2 * pvpanic.c - pvpanic Device Support
3 *
4 * Copyright (C) 2013 Fujitsu.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
22
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/init.h>
26#include <linux/types.h>
27#include <acpi/acpi_bus.h>
28#include <acpi/acpi_drivers.h>
29
30MODULE_AUTHOR("Hu Tao <hutao@cn.fujitsu.com>");
31MODULE_DESCRIPTION("pvpanic device driver");
32MODULE_LICENSE("GPL");
33
34static int pvpanic_add(struct acpi_device *device);
35static int pvpanic_remove(struct acpi_device *device);
36
37static const struct acpi_device_id pvpanic_device_ids[] = {
38 { "QEMU0001", 0 },
39 { "", 0 },
40};
41MODULE_DEVICE_TABLE(acpi, pvpanic_device_ids);
42
43#define PVPANIC_PANICKED (1 << 0)
44
45static u16 port;
46
47static struct acpi_driver pvpanic_driver = {
48 .name = "pvpanic",
49 .class = "QEMU",
50 .ids = pvpanic_device_ids,
51 .ops = {
52 .add = pvpanic_add,
53 .remove = pvpanic_remove,
54 },
55 .owner = THIS_MODULE,
56};
57
58static void
59pvpanic_send_event(unsigned int event)
60{
61 outb(event, port);
62}
63
64static int
65pvpanic_panic_notify(struct notifier_block *nb, unsigned long code,
66 void *unused)
67{
68 pvpanic_send_event(PVPANIC_PANICKED);
69 return NOTIFY_DONE;
70}
71
72static struct notifier_block pvpanic_panic_nb = {
73 .notifier_call = pvpanic_panic_notify,
74};
75
76
77static acpi_status
78pvpanic_walk_resources(struct acpi_resource *res, void *context)
79{
80 switch (res->type) {
81 case ACPI_RESOURCE_TYPE_END_TAG:
82 return AE_OK;
83
84 case ACPI_RESOURCE_TYPE_IO:
85 port = res->data.io.minimum;
86 return AE_OK;
87
88 default:
89 return AE_ERROR;
90 }
91}
92
93static int pvpanic_add(struct acpi_device *device)
94{
95 acpi_status status;
96 u64 ret;
97
98 status = acpi_evaluate_integer(device->handle, "_STA", NULL,
99 &ret);
100
101 if (ACPI_FAILURE(status) || (ret & 0x0B) != 0x0B)
102 return -ENODEV;
103
104 acpi_walk_resources(device->handle, METHOD_NAME__CRS,
105 pvpanic_walk_resources, NULL);
106
107 if (!port)
108 return -ENODEV;
109
110 atomic_notifier_chain_register(&panic_notifier_list,
111 &pvpanic_panic_nb);
112
113 return 0;
114}
115
116static int pvpanic_remove(struct acpi_device *device)
117{
118
119 atomic_notifier_chain_unregister(&panic_notifier_list,
120 &pvpanic_panic_nb);
121 return 0;
122}
123
124module_acpi_driver(pvpanic_driver);