0001
0002
0003
0004
0005
0006
0007
0008 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0009
0010 #include <linux/acpi.h>
0011 #include <linux/device.h>
0012 #include <linux/fs.h>
0013 #include <linux/kernel.h>
0014 #include <linux/module.h>
0015 #include <linux/string.h>
0016 #include <linux/sysfs.h>
0017 #include <linux/types.h>
0018 #include <linux/wmi.h>
0019
0020 #define INTEL_WMI_THUNDERBOLT_GUID "86CCFD48-205E-4A77-9C48-2021CBEDE341"
0021
0022 static ssize_t force_power_store(struct device *dev,
0023 struct device_attribute *attr,
0024 const char *buf, size_t count)
0025 {
0026 struct acpi_buffer input;
0027 acpi_status status;
0028 u8 mode;
0029
0030 input.length = sizeof(u8);
0031 input.pointer = &mode;
0032 mode = hex_to_bin(buf[0]);
0033 dev_dbg(dev, "force_power: storing %#x\n", mode);
0034 if (mode == 0 || mode == 1) {
0035 status = wmi_evaluate_method(INTEL_WMI_THUNDERBOLT_GUID, 0, 1,
0036 &input, NULL);
0037 if (ACPI_FAILURE(status)) {
0038 dev_dbg(dev, "force_power: failed to evaluate ACPI method\n");
0039 return -ENODEV;
0040 }
0041 } else {
0042 dev_dbg(dev, "force_power: unsupported mode\n");
0043 return -EINVAL;
0044 }
0045 return count;
0046 }
0047
0048 static DEVICE_ATTR_WO(force_power);
0049
0050 static struct attribute *tbt_attrs[] = {
0051 &dev_attr_force_power.attr,
0052 NULL
0053 };
0054
0055 static const struct attribute_group tbt_attribute_group = {
0056 .attrs = tbt_attrs,
0057 };
0058
0059 static int intel_wmi_thunderbolt_probe(struct wmi_device *wdev,
0060 const void *context)
0061 {
0062 int ret;
0063
0064 ret = sysfs_create_group(&wdev->dev.kobj, &tbt_attribute_group);
0065 kobject_uevent(&wdev->dev.kobj, KOBJ_CHANGE);
0066 return ret;
0067 }
0068
0069 static void intel_wmi_thunderbolt_remove(struct wmi_device *wdev)
0070 {
0071 sysfs_remove_group(&wdev->dev.kobj, &tbt_attribute_group);
0072 kobject_uevent(&wdev->dev.kobj, KOBJ_CHANGE);
0073 }
0074
0075 static const struct wmi_device_id intel_wmi_thunderbolt_id_table[] = {
0076 { .guid_string = INTEL_WMI_THUNDERBOLT_GUID },
0077 { },
0078 };
0079
0080 static struct wmi_driver intel_wmi_thunderbolt_driver = {
0081 .driver = {
0082 .name = "intel-wmi-thunderbolt",
0083 },
0084 .probe = intel_wmi_thunderbolt_probe,
0085 .remove = intel_wmi_thunderbolt_remove,
0086 .id_table = intel_wmi_thunderbolt_id_table,
0087 };
0088
0089 module_wmi_driver(intel_wmi_thunderbolt_driver);
0090
0091 MODULE_DEVICE_TABLE(wmi, intel_wmi_thunderbolt_id_table);
0092 MODULE_AUTHOR("Mario Limonciello <mario.limonciello@dell.com>");
0093 MODULE_DESCRIPTION("Intel WMI Thunderbolt force power driver");
0094 MODULE_LICENSE("GPL v2");