projects/linux·blob master · refs

90 lines · 2.1 KiB

1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * ACPI Hardware Error Device (PNP0C33) Driver
4 *
5 * Copyright (C) 2010, Intel Corp.
6 * Author: Huang Ying <[email protected]>
7 *
8 * ACPI Hardware Error Device is used to report some hardware errors
9 * notified via SCI, mainly the corrected errors.
10 */
11
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/acpi.h>
16#include <linux/platform_device.h>
17#include <acpi/hed.h>
18
19static const struct acpi_device_id acpi_hed_ids[] = {
20 {"PNP0C33", 0},
21 {"", 0},
22};
23MODULE_DEVICE_TABLE(acpi, acpi_hed_ids);
24
25static bool hed_present;
26
27static BLOCKING_NOTIFIER_HEAD(acpi_hed_notify_list);
28
29int register_acpi_hed_notifier(struct notifier_block *nb)
30{
31 return blocking_notifier_chain_register(&acpi_hed_notify_list, nb);
32}
33EXPORT_SYMBOL_GPL(register_acpi_hed_notifier);
34
35void unregister_acpi_hed_notifier(struct notifier_block *nb)
36{
37 blocking_notifier_chain_unregister(&acpi_hed_notify_list, nb);
38}
39EXPORT_SYMBOL_GPL(unregister_acpi_hed_notifier);
40
41/*
42 * SCI to report hardware error is forwarded to the listeners of HED,
43 * it is used by HEST Generic Hardware Error Source with notify type
44 * SCI.
45 */
46static void acpi_hed_notify(acpi_handle handle, u32 event, void *data)
47{
48 blocking_notifier_call_chain(&acpi_hed_notify_list, 0, NULL);
49}
50
51static int acpi_hed_probe(struct platform_device *pdev)
52{
53 int err;
54
55 /* Only one hardware error device */
56 if (hed_present)
57 return -EINVAL;
58
59 err = devm_acpi_install_notify_handler(&pdev->dev, ACPI_DEVICE_NOTIFY,
60 acpi_hed_notify, NULL);
61 if (err)
62 return err;
63
64 hed_present = true;
65 return 0;
66}
67
68static void acpi_hed_remove(struct platform_device *pdev)
69{
70 hed_present = false;
71}
72
73static struct platform_driver acpi_hed_driver = {
74 .probe = acpi_hed_probe,
75 .remove = acpi_hed_remove,
76 .driver = {
77 .name = "acpi-hardware-error-device",
78 .acpi_match_table = acpi_hed_ids,
79 },
80};
81
82static int __init acpi_hed_driver_init(void)
83{
84 return platform_driver_register(&acpi_hed_driver);
85}
86subsys_initcall(acpi_hed_driver_init);
87
88MODULE_AUTHOR("Huang Ying");
89MODULE_DESCRIPTION("ACPI Hardware Error Device Driver");
90MODULE_LICENSE("GPL");