linux/drivers/platform/x86/intel-wmi-thunderbolt.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * WMI Thunderbolt driver
   4 *
   5 * Copyright (C) 2017 Dell Inc. All Rights Reserved.
   6 */
   7
   8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
   9
  10#include <linux/acpi.h>
  11#include <linux/device.h>
  12#include <linux/fs.h>
  13#include <linux/kernel.h>
  14#include <linux/module.h>
  15#include <linux/string.h>
  16#include <linux/sysfs.h>
  17#include <linux/types.h>
  18#include <linux/wmi.h>
  19
  20#define INTEL_WMI_THUNDERBOLT_GUID "86CCFD48-205E-4A77-9C48-2021CBEDE341"
  21
  22static ssize_t force_power_store(struct device *dev,
  23                                 struct device_attribute *attr,
  24                                 const char *buf, size_t count)
  25{
  26        struct acpi_buffer input;
  27        acpi_status status;
  28        u8 mode;
  29
  30        input.length = sizeof(u8);
  31        input.pointer = &mode;
  32        mode = hex_to_bin(buf[0]);
  33        dev_dbg(dev, "force_power: storing %#x\n", mode);
  34        if (mode == 0 || mode == 1) {
  35                status = wmi_evaluate_method(INTEL_WMI_THUNDERBOLT_GUID, 0, 1,
  36                                             &input, NULL);
  37                if (ACPI_FAILURE(status)) {
  38                        dev_dbg(dev, "force_power: failed to evaluate ACPI method\n");
  39                        return -ENODEV;
  40                }
  41        } else {
  42                dev_dbg(dev, "force_power: unsupported mode\n");
  43                return -EINVAL;
  44        }
  45        return count;
  46}
  47
  48static DEVICE_ATTR_WO(force_power);
  49
  50static struct attribute *tbt_attrs[] = {
  51        &dev_attr_force_power.attr,
  52        NULL
  53};
  54
  55static const struct attribute_group tbt_attribute_group = {
  56        .attrs = tbt_attrs,
  57};
  58
  59static int intel_wmi_thunderbolt_probe(struct wmi_device *wdev,
  60                                       const void *context)
  61{
  62        int ret;
  63
  64        ret = sysfs_create_group(&wdev->dev.kobj, &tbt_attribute_group);
  65        kobject_uevent(&wdev->dev.kobj, KOBJ_CHANGE);
  66        return ret;
  67}
  68
  69static int intel_wmi_thunderbolt_remove(struct wmi_device *wdev)
  70{
  71        sysfs_remove_group(&wdev->dev.kobj, &tbt_attribute_group);
  72        kobject_uevent(&wdev->dev.kobj, KOBJ_CHANGE);
  73        return 0;
  74}
  75
  76static const struct wmi_device_id intel_wmi_thunderbolt_id_table[] = {
  77        { .guid_string = INTEL_WMI_THUNDERBOLT_GUID },
  78        { },
  79};
  80
  81static struct wmi_driver intel_wmi_thunderbolt_driver = {
  82        .driver = {
  83                .name = "intel-wmi-thunderbolt",
  84        },
  85        .probe = intel_wmi_thunderbolt_probe,
  86        .remove = intel_wmi_thunderbolt_remove,
  87        .id_table = intel_wmi_thunderbolt_id_table,
  88};
  89
  90module_wmi_driver(intel_wmi_thunderbolt_driver);
  91
  92MODULE_DEVICE_TABLE(wmi, intel_wmi_thunderbolt_id_table);
  93MODULE_AUTHOR("Mario Limonciello <mario.limonciello@dell.com>");
  94MODULE_DESCRIPTION("Intel WMI Thunderbolt force power driver");
  95MODULE_LICENSE("GPL v2");
  96