summaryrefslogtreecommitdiff
path: root/drivers/misc/pvpanic.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/pvpanic.c')
-rw-r--r--drivers/misc/pvpanic.c59
1 files changed, 54 insertions, 5 deletions
diff --git a/drivers/misc/pvpanic.c b/drivers/misc/pvpanic.c
index 41cab297d66e..9f350e05ef68 100644
--- a/drivers/misc/pvpanic.c
+++ b/drivers/misc/pvpanic.c
@@ -19,6 +19,47 @@
#include <uapi/misc/pvpanic.h>
static void __iomem *base;
+static unsigned int capability = PVPANIC_PANICKED | PVPANIC_CRASH_LOADED;
+static unsigned int events;
+
+static ssize_t capability_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sysfs_emit(buf, "%x\n", capability);
+}
+static DEVICE_ATTR_RO(capability);
+
+static ssize_t events_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ return sysfs_emit(buf, "%x\n", events);
+}
+
+static ssize_t events_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned int tmp;
+ int err;
+
+ err = kstrtouint(buf, 16, &tmp);
+ if (err)
+ return err;
+
+ if ((tmp & capability) != tmp)
+ return -EINVAL;
+
+ events = tmp;
+
+ return count;
+
+}
+static DEVICE_ATTR_RW(events);
+
+static struct attribute *pvpanic_dev_attrs[] = {
+ &dev_attr_capability.attr,
+ &dev_attr_events.attr,
+ NULL
+};
+ATTRIBUTE_GROUPS(pvpanic_dev);
MODULE_AUTHOR("Hu Tao <hutao@cn.fujitsu.com>");
MODULE_DESCRIPTION("pvpanic device driver");
@@ -27,7 +68,8 @@ MODULE_LICENSE("GPL");
static void
pvpanic_send_event(unsigned int event)
{
- iowrite8(event, base);
+ if (event & capability & events)
+ iowrite8(event, base);
}
static int
@@ -73,8 +115,13 @@ static int pvpanic_mmio_probe(struct platform_device *pdev)
return -EINVAL;
}
- atomic_notifier_chain_register(&panic_notifier_list,
- &pvpanic_panic_nb);
+ /* initlize capability by RDPT */
+ capability &= ioread8(base);
+ events = capability;
+
+ if (capability)
+ atomic_notifier_chain_register(&panic_notifier_list,
+ &pvpanic_panic_nb);
return 0;
}
@@ -82,8 +129,9 @@ static int pvpanic_mmio_probe(struct platform_device *pdev)
static int pvpanic_mmio_remove(struct platform_device *pdev)
{
- atomic_notifier_chain_unregister(&panic_notifier_list,
- &pvpanic_panic_nb);
+ if (capability)
+ atomic_notifier_chain_unregister(&panic_notifier_list,
+ &pvpanic_panic_nb);
return 0;
}
@@ -104,6 +152,7 @@ static struct platform_driver pvpanic_mmio_driver = {
.name = "pvpanic-mmio",
.of_match_table = pvpanic_mmio_match,
.acpi_match_table = pvpanic_device_ids,
+ .dev_groups = pvpanic_dev_groups,
},
.probe = pvpanic_mmio_probe,
.remove = pvpanic_mmio_remove,