Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * WMI Thunderbolt driver
0004  *
0005  * Copyright (C) 2017 Dell Inc. All Rights Reserved.
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");