xref: /openbmc/linux/drivers/acpi/hed.c (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
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