intel-wmi-thunderbolt.c 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /*
  2. * WMI Thunderbolt driver
  3. *
  4. * Copyright (C) 2017 Dell Inc. All Rights Reserved.
  5. *
  6. * This program is free software; you can redistribute it and/or modify it
  7. * under the terms of the GNU General Public License version 2 as published
  8. * by the Free Software Foundation.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. */
  15. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  16. #include <linux/acpi.h>
  17. #include <linux/device.h>
  18. #include <linux/fs.h>
  19. #include <linux/kernel.h>
  20. #include <linux/module.h>
  21. #include <linux/string.h>
  22. #include <linux/sysfs.h>
  23. #include <linux/types.h>
  24. #include <linux/wmi.h>
  25. #define INTEL_WMI_THUNDERBOLT_GUID "86CCFD48-205E-4A77-9C48-2021CBEDE341"
  26. static ssize_t force_power_store(struct device *dev,
  27. struct device_attribute *attr,
  28. const char *buf, size_t count)
  29. {
  30. struct acpi_buffer input;
  31. acpi_status status;
  32. u8 mode;
  33. input.length = sizeof(u8);
  34. input.pointer = &mode;
  35. mode = hex_to_bin(buf[0]);
  36. if (mode == 0 || mode == 1) {
  37. status = wmi_evaluate_method(INTEL_WMI_THUNDERBOLT_GUID, 0, 1,
  38. &input, NULL);
  39. if (ACPI_FAILURE(status))
  40. return -ENODEV;
  41. } else {
  42. return -EINVAL;
  43. }
  44. return count;
  45. }
  46. static DEVICE_ATTR_WO(force_power);
  47. static struct attribute *tbt_attrs[] = {
  48. &dev_attr_force_power.attr,
  49. NULL
  50. };
  51. static const struct attribute_group tbt_attribute_group = {
  52. .attrs = tbt_attrs,
  53. };
  54. static int intel_wmi_thunderbolt_probe(struct wmi_device *wdev)
  55. {
  56. int ret;
  57. ret = sysfs_create_group(&wdev->dev.kobj, &tbt_attribute_group);
  58. kobject_uevent(&wdev->dev.kobj, KOBJ_CHANGE);
  59. return ret;
  60. }
  61. static int intel_wmi_thunderbolt_remove(struct wmi_device *wdev)
  62. {
  63. sysfs_remove_group(&wdev->dev.kobj, &tbt_attribute_group);
  64. kobject_uevent(&wdev->dev.kobj, KOBJ_CHANGE);
  65. return 0;
  66. }
  67. static const struct wmi_device_id intel_wmi_thunderbolt_id_table[] = {
  68. { .guid_string = INTEL_WMI_THUNDERBOLT_GUID },
  69. { },
  70. };
  71. static struct wmi_driver intel_wmi_thunderbolt_driver = {
  72. .driver = {
  73. .name = "intel-wmi-thunderbolt",
  74. },
  75. .probe = intel_wmi_thunderbolt_probe,
  76. .remove = intel_wmi_thunderbolt_remove,
  77. .id_table = intel_wmi_thunderbolt_id_table,
  78. };
  79. module_wmi_driver(intel_wmi_thunderbolt_driver);
  80. MODULE_ALIAS("wmi:" INTEL_WMI_THUNDERBOLT_GUID);
  81. MODULE_AUTHOR("Mario Limonciello <mario.limonciello@dell.com>");
  82. MODULE_DESCRIPTION("Intel WMI Thunderbolt force power driver");
  83. MODULE_LICENSE("GPL");