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 const struct class firmware_attributes_class = {
14  	.name = "firmware-attributes",
15  };
16  
fw_attributes_class_get(const struct class ** fw_attr_class)17  int fw_attributes_class_get(const 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  
fw_attributes_class_put(void)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_DESCRIPTION("Firmware attributes class helper module");
53  MODULE_LICENSE("GPL");
54