summaryrefslogtreecommitdiff
path: root/drivers/platform
diff options
context:
space:
mode:
authorMark Pearson <markpearson@lenovo.com>2021-05-30 18:31:09 -0400
committerHans de Goede <hdegoede@redhat.com>2021-06-16 17:47:51 +0200
commit17b707fe5fbd3c019691873c1c11bddb0e0f7225 (patch)
treef3a84c8296fc4c32e5c8cdf6b2e9978f086c353c /drivers/platform
parent6cbaee2e109ed0f7327a2d3cbb412f36fd8873e0 (diff)
platform/x86: firmware_attributes_class: Create helper file for handling firmware-attributes class registration events
This offers shared code for registering the firmware_attributes_class, which is used by the Dell and Lenovo WMI management drivers. Reported-by: kernel test robot <lkp@intel.com> Signed-off-by: Mark Pearson <markpearson@lenovo.com> Link: https://lore.kernel.org/r/20210530223111.25929-1-markpearson@lenovo.com Reviewed-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/x86/Kconfig4
-rw-r--r--drivers/platform/x86/Makefile1
-rw-r--r--drivers/platform/x86/firmware_attributes_class.c52
-rw-r--r--drivers/platform/x86/firmware_attributes_class.h11
4 files changed, 68 insertions, 0 deletions
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 9a668dae2738..d6fa071d78de 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -1077,6 +1077,10 @@ config TOUCHSCREEN_DMI
the OS-image for the device. This option supplies the missing info.
Enable this for x86 tablets with Silead or Chipone touchscreens.
+config FW_ATTR_CLASS
+ tristate
+ default n
+
config INTEL_IMR
bool "Intel Isolated Memory Region support"
depends on X86_INTEL_QUARK && IOSF_MBI
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index 415bec18ece2..98c776967fa0 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -111,6 +111,7 @@ obj-$(CONFIG_SYSTEM76_ACPI) += system76_acpi.o
obj-$(CONFIG_TOPSTAR_LAPTOP) += topstar-laptop.o
# Platform drivers
+obj-$(CONFIG_FW_ATTR_CLASS) += firmware_attributes_class.o
obj-$(CONFIG_I2C_MULTI_INSTANTIATE) += i2c-multi-instantiate.o
obj-$(CONFIG_MLX_PLATFORM) += mlx-platform.o
obj-$(CONFIG_TOUCHSCREEN_DMI) += touchscreen_dmi.o
diff --git a/drivers/platform/x86/firmware_attributes_class.c b/drivers/platform/x86/firmware_attributes_class.c
new file mode 100644
index 000000000000..d62ec3d71ede
--- /dev/null
+++ b/drivers/platform/x86/firmware_attributes_class.c
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/* Firmware attributes class helper module */
+
+#include <linux/mutex.h>
+#include <linux/device/class.h>
+#include <linux/module.h>
+#include "firmware_attributes_class.h"
+
+static DEFINE_MUTEX(fw_attr_lock);
+int fw_attr_inuse;
+
+static struct class firmware_attributes_class = {
+ .name = "firmware-attributes",
+};
+
+int fw_attributes_class_get(struct class **fw_attr_class)
+{
+ int err;
+
+ mutex_lock(&fw_attr_lock);
+ if (!fw_attr_inuse) { /*first time class is being used*/
+ err = class_register(&firmware_attributes_class);
+ if (err) {
+ mutex_unlock(&fw_attr_lock);
+ return err;
+ }
+ }
+ fw_attr_inuse++;
+ *fw_attr_class = &firmware_attributes_class;
+ mutex_unlock(&fw_attr_lock);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(fw_attributes_class_get);
+
+int fw_attributes_class_put(void)
+{
+ mutex_lock(&fw_attr_lock);
+ if (!fw_attr_inuse) {
+ mutex_unlock(&fw_attr_lock);
+ return -EINVAL;
+ }
+ fw_attr_inuse--;
+ if (!fw_attr_inuse) /* No more consumers */
+ class_unregister(&firmware_attributes_class);
+ mutex_unlock(&fw_attr_lock);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(fw_attributes_class_put);
+
+MODULE_AUTHOR("Mark Pearson <markpearson@lenovo.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/platform/x86/firmware_attributes_class.h b/drivers/platform/x86/firmware_attributes_class.h
new file mode 100644
index 000000000000..486485cb1f54
--- /dev/null
+++ b/drivers/platform/x86/firmware_attributes_class.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/* Firmware attributes class helper module */
+
+#ifndef FW_ATTR_CLASS_H
+#define FW_ATTR_CLASS_H
+
+int fw_attributes_class_get(struct class **fw_attr_class);
+int fw_attributes_class_put(void);
+
+#endif /* FW_ATTR_CLASS_H */