Many older WMI drivers cannot be instantiated multiple times for two reasons: - they are using the legacy GUID-based WMI API - they are singletons (with global state) Prevent such WMI drivers from binding to WMI devices with a duplicated GUID, as this would mean that the WMI driver will be instantiated at least two times (one for the original GUID and one for the duplicated GUID). WMI drivers which can be instantiated multiple times can signal this by setting a flag inside struct wmi_driver. Tested on a ASUS Prime B650-Plus. Signed-off-by: Armin Wolf <W_Armin@gmx.de> Link: https://lore.kernel.org/r/20240226193557.2888-2-W_Armin@gmx.de Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
74 lines
1.8 KiB
C
74 lines
1.8 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* WMI Thunderbolt driver
|
|
*
|
|
* Copyright (C) 2017 Dell Inc. All Rights Reserved.
|
|
*/
|
|
|
|
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
|
|
|
#include <linux/acpi.h>
|
|
#include <linux/device.h>
|
|
#include <linux/fs.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/module.h>
|
|
#include <linux/string.h>
|
|
#include <linux/sysfs.h>
|
|
#include <linux/types.h>
|
|
#include <linux/wmi.h>
|
|
|
|
#define INTEL_WMI_THUNDERBOLT_GUID "86CCFD48-205E-4A77-9C48-2021CBEDE341"
|
|
|
|
static ssize_t force_power_store(struct device *dev,
|
|
struct device_attribute *attr,
|
|
const char *buf, size_t count)
|
|
{
|
|
struct acpi_buffer input;
|
|
acpi_status status;
|
|
u8 mode;
|
|
|
|
input.length = sizeof(u8);
|
|
input.pointer = &mode;
|
|
mode = hex_to_bin(buf[0]);
|
|
dev_dbg(dev, "force_power: storing %#x\n", mode);
|
|
if (mode == 0 || mode == 1) {
|
|
status = wmidev_evaluate_method(to_wmi_device(dev), 0, 1, &input, NULL);
|
|
if (ACPI_FAILURE(status)) {
|
|
dev_dbg(dev, "force_power: failed to evaluate ACPI method\n");
|
|
return -ENODEV;
|
|
}
|
|
} else {
|
|
dev_dbg(dev, "force_power: unsupported mode\n");
|
|
return -EINVAL;
|
|
}
|
|
return count;
|
|
}
|
|
|
|
static DEVICE_ATTR_WO(force_power);
|
|
|
|
static struct attribute *tbt_attrs[] = {
|
|
&dev_attr_force_power.attr,
|
|
NULL
|
|
};
|
|
ATTRIBUTE_GROUPS(tbt);
|
|
|
|
static const struct wmi_device_id intel_wmi_thunderbolt_id_table[] = {
|
|
{ .guid_string = INTEL_WMI_THUNDERBOLT_GUID },
|
|
{ },
|
|
};
|
|
|
|
static struct wmi_driver intel_wmi_thunderbolt_driver = {
|
|
.driver = {
|
|
.name = "intel-wmi-thunderbolt",
|
|
.dev_groups = tbt_groups,
|
|
},
|
|
.id_table = intel_wmi_thunderbolt_id_table,
|
|
.no_singleton = true,
|
|
};
|
|
|
|
module_wmi_driver(intel_wmi_thunderbolt_driver);
|
|
|
|
MODULE_DEVICE_TABLE(wmi, intel_wmi_thunderbolt_id_table);
|
|
MODULE_AUTHOR("Mario Limonciello <mario.limonciello@dell.com>");
|
|
MODULE_DESCRIPTION("Intel WMI Thunderbolt force power driver");
|
|
MODULE_LICENSE("GPL v2");
|