RISC-V: Fix a race condition during kernel stack overflow
[linux-2.6-microblaze.git] / drivers / platform / x86 / firmware_attributes_class.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /* Firmware attributes class helper module */
4
5 #include <linux/mutex.h>
6 #include <linux/device/class.h>
7 #include <linux/module.h>
8 #include "firmware_attributes_class.h"
9
10 static DEFINE_MUTEX(fw_attr_lock);
11 static int fw_attr_inuse;
12
13 static struct class firmware_attributes_class = {
14         .name = "firmware-attributes",
15 };
16
17 int fw_attributes_class_get(struct class **fw_attr_class)
18 {
19         int err;
20
21         mutex_lock(&fw_attr_lock);
22         if (!fw_attr_inuse) { /*first time class is being used*/
23                 err = class_register(&firmware_attributes_class);
24                 if (err) {
25                         mutex_unlock(&fw_attr_lock);
26                         return err;
27                 }
28         }
29         fw_attr_inuse++;
30         *fw_attr_class = &firmware_attributes_class;
31         mutex_unlock(&fw_attr_lock);
32         return 0;
33 }
34 EXPORT_SYMBOL_GPL(fw_attributes_class_get);
35
36 int fw_attributes_class_put(void)
37 {
38         mutex_lock(&fw_attr_lock);
39         if (!fw_attr_inuse) {
40                 mutex_unlock(&fw_attr_lock);
41                 return -EINVAL;
42         }
43         fw_attr_inuse--;
44         if (!fw_attr_inuse) /* No more consumers */
45                 class_unregister(&firmware_attributes_class);
46         mutex_unlock(&fw_attr_lock);
47         return 0;
48 }
49 EXPORT_SYMBOL_GPL(fw_attributes_class_put);
50
51 MODULE_AUTHOR("Mark Pearson <markpearson@lenovo.com>");
52 MODULE_LICENSE("GPL");