11802d0beSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2801eab81SHuang Ying /*
3801eab81SHuang Ying * ACPI Hardware Error Device (PNP0C33) Driver
4801eab81SHuang Ying *
5801eab81SHuang Ying * Copyright (C) 2010, Intel Corp.
6801eab81SHuang Ying * Author: Huang Ying <ying.huang@intel.com>
7801eab81SHuang Ying *
8801eab81SHuang Ying * ACPI Hardware Error Device is used to report some hardware errors
9801eab81SHuang Ying * notified via SCI, mainly the corrected errors.
10801eab81SHuang Ying */
11801eab81SHuang Ying
12801eab81SHuang Ying #include <linux/kernel.h>
13801eab81SHuang Ying #include <linux/module.h>
14801eab81SHuang Ying #include <linux/init.h>
15801eab81SHuang Ying #include <linux/acpi.h>
16801eab81SHuang Ying #include <acpi/hed.h>
17801eab81SHuang Ying
1869cda6e0SMathias Krause static const struct acpi_device_id acpi_hed_ids[] = {
19801eab81SHuang Ying {"PNP0C33", 0},
20801eab81SHuang Ying {"", 0},
21801eab81SHuang Ying };
22801eab81SHuang Ying MODULE_DEVICE_TABLE(acpi, acpi_hed_ids);
23801eab81SHuang Ying
24801eab81SHuang Ying static acpi_handle hed_handle;
25801eab81SHuang Ying
26801eab81SHuang Ying static BLOCKING_NOTIFIER_HEAD(acpi_hed_notify_list);
27801eab81SHuang Ying
register_acpi_hed_notifier(struct notifier_block * nb)28801eab81SHuang Ying int register_acpi_hed_notifier(struct notifier_block *nb)
29801eab81SHuang Ying {
30801eab81SHuang Ying return blocking_notifier_chain_register(&acpi_hed_notify_list, nb);
31801eab81SHuang Ying }
32801eab81SHuang Ying EXPORT_SYMBOL_GPL(register_acpi_hed_notifier);
33801eab81SHuang Ying
unregister_acpi_hed_notifier(struct notifier_block * nb)34801eab81SHuang Ying void unregister_acpi_hed_notifier(struct notifier_block *nb)
35801eab81SHuang Ying {
36801eab81SHuang Ying blocking_notifier_chain_unregister(&acpi_hed_notify_list, nb);
37801eab81SHuang Ying }
38801eab81SHuang Ying EXPORT_SYMBOL_GPL(unregister_acpi_hed_notifier);
39801eab81SHuang Ying
40801eab81SHuang Ying /*
41801eab81SHuang Ying * SCI to report hardware error is forwarded to the listeners of HED,
42801eab81SHuang Ying * it is used by HEST Generic Hardware Error Source with notify type
43801eab81SHuang Ying * SCI.
44801eab81SHuang Ying */
acpi_hed_notify(acpi_handle handle,u32 event,void * data)45*898ff0f0SMichal Wilczynski static void acpi_hed_notify(acpi_handle handle, u32 event, void *data)
46801eab81SHuang Ying {
47801eab81SHuang Ying blocking_notifier_call_chain(&acpi_hed_notify_list, 0, NULL);
48801eab81SHuang Ying }
49801eab81SHuang Ying
acpi_hed_add(struct acpi_device * device)50da095fd3SBill Pemberton static int acpi_hed_add(struct acpi_device *device)
51801eab81SHuang Ying {
52*898ff0f0SMichal Wilczynski int err;
53*898ff0f0SMichal Wilczynski
54801eab81SHuang Ying /* Only one hardware error device */
55801eab81SHuang Ying if (hed_handle)
56801eab81SHuang Ying return -EINVAL;
57801eab81SHuang Ying hed_handle = device->handle;
58*898ff0f0SMichal Wilczynski
59*898ff0f0SMichal Wilczynski err = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY,
60*898ff0f0SMichal Wilczynski acpi_hed_notify);
61*898ff0f0SMichal Wilczynski if (err)
62*898ff0f0SMichal Wilczynski hed_handle = NULL;
63*898ff0f0SMichal Wilczynski
64*898ff0f0SMichal Wilczynski return err;
65801eab81SHuang Ying }
66801eab81SHuang Ying
acpi_hed_remove(struct acpi_device * device)676c0eb5baSDawei Li static void acpi_hed_remove(struct acpi_device *device)
68801eab81SHuang Ying {
69*898ff0f0SMichal Wilczynski acpi_dev_remove_notify_handler(device, ACPI_DEVICE_NOTIFY,
70*898ff0f0SMichal Wilczynski acpi_hed_notify);
71801eab81SHuang Ying hed_handle = NULL;
72801eab81SHuang Ying }
73801eab81SHuang Ying
74801eab81SHuang Ying static struct acpi_driver acpi_hed_driver = {
75801eab81SHuang Ying .name = "hardware_error_device",
76801eab81SHuang Ying .class = "hardware_error",
77801eab81SHuang Ying .ids = acpi_hed_ids,
78801eab81SHuang Ying .ops = {
79801eab81SHuang Ying .add = acpi_hed_add,
80801eab81SHuang Ying .remove = acpi_hed_remove,
81801eab81SHuang Ying },
82801eab81SHuang Ying };
838fe4bf6fSMika Westerberg module_acpi_driver(acpi_hed_driver);
84801eab81SHuang Ying
85801eab81SHuang Ying MODULE_AUTHOR("Huang Ying");
86801eab81SHuang Ying MODULE_DESCRIPTION("ACPI Hardware Error Device Driver");
87801eab81SHuang Ying MODULE_LICENSE("GPL");
88