xref: /openbmc/linux/drivers/platform/x86/intel/wmi/thunderbolt.c (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
195c3e4b4SKate Hsuan // SPDX-License-Identifier: GPL-2.0
295c3e4b4SKate Hsuan /*
395c3e4b4SKate Hsuan  * WMI Thunderbolt driver
495c3e4b4SKate Hsuan  *
595c3e4b4SKate Hsuan  * Copyright (C) 2017 Dell Inc. All Rights Reserved.
695c3e4b4SKate Hsuan  */
795c3e4b4SKate Hsuan 
895c3e4b4SKate Hsuan #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
995c3e4b4SKate Hsuan 
1095c3e4b4SKate Hsuan #include <linux/acpi.h>
1195c3e4b4SKate Hsuan #include <linux/device.h>
1295c3e4b4SKate Hsuan #include <linux/fs.h>
1395c3e4b4SKate Hsuan #include <linux/kernel.h>
1495c3e4b4SKate Hsuan #include <linux/module.h>
1595c3e4b4SKate Hsuan #include <linux/string.h>
1695c3e4b4SKate Hsuan #include <linux/sysfs.h>
1795c3e4b4SKate Hsuan #include <linux/types.h>
1895c3e4b4SKate Hsuan #include <linux/wmi.h>
1995c3e4b4SKate Hsuan 
2095c3e4b4SKate Hsuan #define INTEL_WMI_THUNDERBOLT_GUID "86CCFD48-205E-4A77-9C48-2021CBEDE341"
2195c3e4b4SKate Hsuan 
force_power_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)2295c3e4b4SKate Hsuan static ssize_t force_power_store(struct device *dev,
2395c3e4b4SKate Hsuan 				 struct device_attribute *attr,
2495c3e4b4SKate Hsuan 				 const char *buf, size_t count)
2595c3e4b4SKate Hsuan {
2695c3e4b4SKate Hsuan 	struct acpi_buffer input;
2795c3e4b4SKate Hsuan 	acpi_status status;
2895c3e4b4SKate Hsuan 	u8 mode;
2995c3e4b4SKate Hsuan 
3095c3e4b4SKate Hsuan 	input.length = sizeof(u8);
3195c3e4b4SKate Hsuan 	input.pointer = &mode;
3295c3e4b4SKate Hsuan 	mode = hex_to_bin(buf[0]);
3395c3e4b4SKate Hsuan 	dev_dbg(dev, "force_power: storing %#x\n", mode);
3495c3e4b4SKate Hsuan 	if (mode == 0 || mode == 1) {
3595c3e4b4SKate Hsuan 		status = wmi_evaluate_method(INTEL_WMI_THUNDERBOLT_GUID, 0, 1,
3695c3e4b4SKate Hsuan 					     &input, NULL);
3795c3e4b4SKate Hsuan 		if (ACPI_FAILURE(status)) {
3895c3e4b4SKate Hsuan 			dev_dbg(dev, "force_power: failed to evaluate ACPI method\n");
3995c3e4b4SKate Hsuan 			return -ENODEV;
4095c3e4b4SKate Hsuan 		}
4195c3e4b4SKate Hsuan 	} else {
4295c3e4b4SKate Hsuan 		dev_dbg(dev, "force_power: unsupported mode\n");
4395c3e4b4SKate Hsuan 		return -EINVAL;
4495c3e4b4SKate Hsuan 	}
4595c3e4b4SKate Hsuan 	return count;
4695c3e4b4SKate Hsuan }
4795c3e4b4SKate Hsuan 
4895c3e4b4SKate Hsuan static DEVICE_ATTR_WO(force_power);
4995c3e4b4SKate Hsuan 
5095c3e4b4SKate Hsuan static struct attribute *tbt_attrs[] = {
5195c3e4b4SKate Hsuan 	&dev_attr_force_power.attr,
5295c3e4b4SKate Hsuan 	NULL
5395c3e4b4SKate Hsuan };
54*4e3d731bSShyam Sundar S K ATTRIBUTE_GROUPS(tbt);
5595c3e4b4SKate Hsuan 
5695c3e4b4SKate Hsuan static const struct wmi_device_id intel_wmi_thunderbolt_id_table[] = {
5795c3e4b4SKate Hsuan 	{ .guid_string = INTEL_WMI_THUNDERBOLT_GUID },
5895c3e4b4SKate Hsuan 	{ },
5995c3e4b4SKate Hsuan };
6095c3e4b4SKate Hsuan 
6195c3e4b4SKate Hsuan static struct wmi_driver intel_wmi_thunderbolt_driver = {
6295c3e4b4SKate Hsuan 	.driver = {
6395c3e4b4SKate Hsuan 		.name = "intel-wmi-thunderbolt",
64*4e3d731bSShyam Sundar S K 		.dev_groups = tbt_groups,
6595c3e4b4SKate Hsuan 	},
6695c3e4b4SKate Hsuan 	.id_table = intel_wmi_thunderbolt_id_table,
6795c3e4b4SKate Hsuan };
6895c3e4b4SKate Hsuan 
6995c3e4b4SKate Hsuan module_wmi_driver(intel_wmi_thunderbolt_driver);
7095c3e4b4SKate Hsuan 
7195c3e4b4SKate Hsuan MODULE_DEVICE_TABLE(wmi, intel_wmi_thunderbolt_id_table);
7295c3e4b4SKate Hsuan MODULE_AUTHOR("Mario Limonciello <mario.limonciello@dell.com>");
7395c3e4b4SKate Hsuan MODULE_DESCRIPTION("Intel WMI Thunderbolt force power driver");
7495c3e4b4SKate Hsuan MODULE_LICENSE("GPL v2");
75