// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Linux driver for WMI sensor information on Dell notebooks.
 *
 * Copyright (C) 2022 Armin Wolf <W_Armin@gmx.de>
 */

#define pr_format(fmt) KBUILD_MODNAME ": " fmt

#include <linux/acpi.h>
#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/device/driver.h>
#include <linux/dev_printk.h>
#include <linux/errno.h>
#include <linux/kconfig.h>
#include <linux/kernel.h>
#include <linux/hwmon.h>
#include <linux/kstrtox.h>
#include <linux/math64.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/limits.h>
#include <linux/pm.h>
#include <linux/power_supply.h>
#include <linux/printk.h>
#include <linux/seq_file.h>
#include <linux/sysfs.h>
#include <linux/types.h>
#include <linux/wmi.h>

#include <acpi/battery.h>

#include <asm/unaligned.h>

#define DRIVER_NAME	"dell-wmi-ddv"

#define DELL_DDV_SUPPORTED_VERSION_MIN	2
#define DELL_DDV_SUPPORTED_VERSION_MAX	3
#define DELL_DDV_GUID	"8A42EA14-4F2A-FD45-6422-0087F7A7E608"

#define DELL_EPPID_LENGTH	20
#define DELL_EPPID_EXT_LENGTH	23

static bool force;
module_param_unsafe(force, bool, 0);
MODULE_PARM_DESC(force, "Force loading without checking for supported WMI interface versions");

enum dell_ddv_method {
	DELL_DDV_BATTERY_DESIGN_CAPACITY	= 0x01,
	DELL_DDV_BATTERY_FULL_CHARGE_CAPACITY	= 0x02,
	DELL_DDV_BATTERY_MANUFACTURE_NAME	= 0x03,
	DELL_DDV_BATTERY_MANUFACTURE_DATE	= 0x04,
	DELL_DDV_BATTERY_SERIAL_NUMBER		= 0x05,
	DELL_DDV_BATTERY_CHEMISTRY_VALUE	= 0x06,
	DELL_DDV_BATTERY_TEMPERATURE		= 0x07,
	DELL_DDV_BATTERY_CURRENT		= 0x08,
	DELL_DDV_BATTERY_VOLTAGE		= 0x09,
	DELL_DDV_BATTERY_MANUFACTURER_ACCESS	= 0x0A,
	DELL_DDV_BATTERY_RELATIVE_CHARGE_STATE	= 0x0B,
	DELL_DDV_BATTERY_CYCLE_COUNT		= 0x0C,
	DELL_DDV_BATTERY_EPPID			= 0x0D,
	DELL_DDV_BATTERY_RAW_ANALYTICS_START	= 0x0E,
	DELL_DDV_BATTERY_RAW_ANALYTICS		= 0x0F,
	DELL_DDV_BATTERY_DESIGN_VOLTAGE		= 0x10,
	DELL_DDV_BATTERY_RAW_ANALYTICS_A_BLOCK	= 0x11, /* version 3 */

	DELL_DDV_INTERFACE_VERSION		= 0x12,

	DELL_DDV_FAN_SENSOR_INFORMATION		= 0x20,
	DELL_DDV_THERMAL_SENSOR_INFORMATION	= 0x22,
};

struct fan_sensor_entry {
	u8 type;
	__le16 rpm;
} __packed;

struct thermal_sensor_entry {
	u8 type;
	s8 now;
	s8 min;
	s8 max;
	u8 unknown;
} __packed;

struct combined_channel_info {
	struct hwmon_channel_info info;
	u32 config[];
};

struct combined_chip_info {
	struct hwmon_chip_info chip;
	const struct hwmon_channel_info *info[];
};

struct dell_wmi_ddv_sensors {
	bool active;
	struct mutex lock;	/* protect caching */
	unsigned long timestamp;
	union acpi_object *obj;
	u64 entries;
};

struct dell_wmi_ddv_data {
	struct acpi_battery_hook hook;
	struct device_attribute temp_attr;
	struct device_attribute eppid_attr;
	struct dell_wmi_ddv_sensors fans;
	struct dell_wmi_ddv_sensors temps;
	struct wmi_device *wdev;
};

static const char * const fan_labels[] = {
	"CPU Fan",
	"Chassis Motherboard Fan",
	"Video Fan",
	"Power Supply Fan",
	"Chipset Fan",
	"Memory Fan",
	"PCI Fan",
	"HDD Fan",
};

static const char * const fan_dock_labels[] = {
	"Docking Chassis/Motherboard Fan",
	"Docking Video Fan",
	"Docking Power Supply Fan",
	"Docking Chipset Fan",
};

static int dell_wmi_ddv_query_type(struct wmi_device *wdev, enum dell_ddv_method method, u32 arg,
				   union acpi_object **result, acpi_object_type type)
{
	struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL };
	const struct acpi_buffer in = {
		.length = sizeof(arg),
		.pointer = &arg,
	};
	union acpi_object *obj;
	acpi_status ret;

	ret = wmidev_evaluate_method(wdev, 0x0, method, &in, &out);
	if (ACPI_FAILURE(ret))
		return -EIO;

	obj = out.pointer;
	if (!obj)
		return -ENODATA;

	if (obj->type != type) {
		kfree(obj);
		return -ENOMSG;
	}

	*result = obj;

	return 0;
}

static int dell_wmi_ddv_query_integer(struct wmi_device *wdev, enum dell_ddv_method method,
				      u32 arg, u32 *res)
{
	union acpi_object *obj;
	int ret;

	ret = dell_wmi_ddv_query_type(wdev, method, arg, &obj, ACPI_TYPE_INTEGER);
	if (ret < 0)
		return ret;

	if (obj->integer.value <= U32_MAX)
		*res = (u32)obj->integer.value;
	else
		ret = -ERANGE;

	kfree(obj);

	return ret;
}

static int dell_wmi_ddv_query_buffer(struct wmi_device *wdev, enum dell_ddv_method method,
				     u32 arg, union acpi_object **result)
{
	union acpi_object *obj;
	u64 buffer_size;
	int ret;

	ret = dell_wmi_ddv_query_type(wdev, method, arg, &obj, ACPI_TYPE_PACKAGE);
	if (ret < 0)
		return ret;

	if (obj->package.count != 2 ||
	    obj->package.elements[0].type != ACPI_TYPE_INTEGER ||
	    obj->package.elements[1].type != ACPI_TYPE_BUFFER) {
		ret = -ENOMSG;

		goto err_free;
	}

	buffer_size = obj->package.elements[0].integer.value;

	if (!buffer_size) {
		ret = -ENODATA;

		goto err_free;
	}

	if (buffer_size > obj->package.elements[1].buffer.length) {
		dev_warn(&wdev->dev,
			 FW_WARN "WMI buffer size (%llu) exceeds ACPI buffer size (%d)\n",
			 buffer_size, obj->package.elements[1].buffer.length);
		ret = -EMSGSIZE;

		goto err_free;
	}

	*result = obj;

	return 0;

err_free:
	kfree(obj);

	return ret;
}

static int dell_wmi_ddv_query_string(struct wmi_device *wdev, enum dell_ddv_method method,
				     u32 arg, union acpi_object **result)
{
	return dell_wmi_ddv_query_type(wdev, method, arg, result, ACPI_TYPE_STRING);
}

/*
 * Needs to be called with lock held, except during initialization.
 */
static int dell_wmi_ddv_update_sensors(struct wmi_device *wdev, enum dell_ddv_method method,
				       struct dell_wmi_ddv_sensors *sensors, size_t entry_size)
{
	u64 buffer_size, rem, entries;
	union acpi_object *obj;
	u8 *buffer;
	int ret;

	if (sensors->obj) {
		if (time_before(jiffies, sensors->timestamp + HZ))
			return 0;

		kfree(sensors->obj);
		sensors->obj = NULL;
	}

	ret = dell_wmi_ddv_query_buffer(wdev, method, 0, &obj);
	if (ret < 0)
		return ret;

	/* buffer format sanity check */
	buffer_size = obj->package.elements[0].integer.value;
	buffer = obj->package.elements[1].buffer.pointer;
	entries = div64_u64_rem(buffer_size, entry_size, &rem);
	if (rem != 1 || buffer[buffer_size - 1] != 0xff) {
		ret = -ENOMSG;
		goto err_free;
	}

	if (!entries) {
		ret = -ENODATA;
		goto err_free;
	}

	sensors->obj = obj;
	sensors->entries = entries;
	sensors->timestamp = jiffies;

	return 0;

err_free:
	kfree(obj);

	return ret;
}

static umode_t dell_wmi_ddv_is_visible(const void *drvdata, enum hwmon_sensor_types type, u32 attr,
				       int channel)
{
	return 0444;
}

static int dell_wmi_ddv_fan_read_channel(struct dell_wmi_ddv_data *data, u32 attr, int channel,
					 long *val)
{
	struct fan_sensor_entry *entry;
	int ret;

	ret = dell_wmi_ddv_update_sensors(data->wdev, DELL_DDV_FAN_SENSOR_INFORMATION,
					  &data->fans, sizeof(*entry));
	if (ret < 0)
		return ret;

	if (channel >= data->fans.entries)
		return -ENXIO;

	entry = (struct fan_sensor_entry *)data->fans.obj->package.elements[1].buffer.pointer;
	switch (attr) {
	case hwmon_fan_input:
		*val = get_unaligned_le16(&entry[channel].rpm);
		return 0;
	default:
		break;
	}

	return -EOPNOTSUPP;
}

static int dell_wmi_ddv_temp_read_channel(struct dell_wmi_ddv_data *data, u32 attr, int channel,
					  long *val)
{
	struct thermal_sensor_entry *entry;
	int ret;

	ret = dell_wmi_ddv_update_sensors(data->wdev, DELL_DDV_THERMAL_SENSOR_INFORMATION,
					  &data->temps, sizeof(*entry));
	if (ret < 0)
		return ret;

	if (channel >= data->temps.entries)
		return -ENXIO;

	entry = (struct thermal_sensor_entry *)data->temps.obj->package.elements[1].buffer.pointer;
	switch (attr) {
	case hwmon_temp_input:
		*val = entry[channel].now * 1000;
		return 0;
	case hwmon_temp_min:
		*val = entry[channel].min * 1000;
		return 0;
	case hwmon_temp_max:
		*val = entry[channel].max * 1000;
		return 0;
	default:
		break;
	}

	return -EOPNOTSUPP;
}

static int dell_wmi_ddv_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
			     int channel, long *val)
{
	struct dell_wmi_ddv_data *data = dev_get_drvdata(dev);
	int ret;

	switch (type) {
	case hwmon_fan:
		mutex_lock(&data->fans.lock);
		ret = dell_wmi_ddv_fan_read_channel(data, attr, channel, val);
		mutex_unlock(&data->fans.lock);
		return ret;
	case hwmon_temp:
		mutex_lock(&data->temps.lock);
		ret = dell_wmi_ddv_temp_read_channel(data, attr, channel, val);
		mutex_unlock(&data->temps.lock);
		return ret;
	default:
		break;
	}

	return -EOPNOTSUPP;
}

static int dell_wmi_ddv_fan_read_string(struct dell_wmi_ddv_data *data, int channel,
					const char **str)
{
	struct fan_sensor_entry *entry;
	int ret;
	u8 type;

	ret = dell_wmi_ddv_update_sensors(data->wdev, DELL_DDV_FAN_SENSOR_INFORMATION,
					  &data->fans, sizeof(*entry));
	if (ret < 0)
		return ret;

	if (channel >= data->fans.entries)
		return -ENXIO;

	entry = (struct fan_sensor_entry *)data->fans.obj->package.elements[1].buffer.pointer;
	type = entry[channel].type;
	switch (type) {
	case 0x00 ... 0x07:
		*str = fan_labels[type];
		break;
	case 0x11 ... 0x14:
		*str = fan_dock_labels[type - 0x11];
		break;
	default:
		*str = "Unknown Fan";
		break;
	}

	return 0;
}

static int dell_wmi_ddv_temp_read_string(struct dell_wmi_ddv_data *data, int channel,
					 const char **str)
{
	struct thermal_sensor_entry *entry;
	int ret;

	ret = dell_wmi_ddv_update_sensors(data->wdev, DELL_DDV_THERMAL_SENSOR_INFORMATION,
					  &data->temps, sizeof(*entry));
	if (ret < 0)
		return ret;

	if (channel >= data->temps.entries)
		return -ENXIO;

	entry = (struct thermal_sensor_entry *)data->temps.obj->package.elements[1].buffer.pointer;
	switch (entry[channel].type) {
	case 0x00:
		*str = "CPU";
		break;
	case 0x11:
		*str = "Video";
		break;
	case 0x22:
		*str = "Memory"; /* sometimes called DIMM */
		break;
	case 0x33:
		*str = "Other";
		break;
	case 0x44:
		*str = "Ambient"; /* sometimes called SKIN */
		break;
	case 0x52:
		*str = "SODIMM";
		break;
	case 0x55:
		*str = "HDD";
		break;
	case 0x62:
		*str = "SODIMM 2";
		break;
	case 0x73:
		*str = "NB";
		break;
	case 0x83:
		*str = "Charger";
		break;
	case 0xbb:
		*str = "Memory 3";
		break;
	default:
		*str = "Unknown";
		break;
	}

	return 0;
}

static int dell_wmi_ddv_read_string(struct device *dev, enum hwmon_sensor_types type, u32 attr,
				    int channel, const char **str)
{
	struct dell_wmi_ddv_data *data = dev_get_drvdata(dev);
	int ret;

	switch (type) {
	case hwmon_fan:
		switch (attr) {
		case hwmon_fan_label:
			mutex_lock(&data->fans.lock);
			ret = dell_wmi_ddv_fan_read_string(data, channel, str);
			mutex_unlock(&data->fans.lock);
			return ret;
		default:
			break;
		}
		break;
	case hwmon_temp:
		switch (attr) {
		case hwmon_temp_label:
			mutex_lock(&data->temps.lock);
			ret = dell_wmi_ddv_temp_read_string(data, channel, str);
			mutex_unlock(&data->temps.lock);
			return ret;
		default:
			break;
		}
		break;
	default:
		break;
	}

	return -EOPNOTSUPP;
}

static const struct hwmon_ops dell_wmi_ddv_ops = {
	.is_visible = dell_wmi_ddv_is_visible,
	.read = dell_wmi_ddv_read,
	.read_string = dell_wmi_ddv_read_string,
};

static struct hwmon_channel_info *dell_wmi_ddv_channel_create(struct device *dev, u64 count,
							      enum hwmon_sensor_types type,
							      u32 config)
{
	struct combined_channel_info *cinfo;
	int i;

	cinfo = devm_kzalloc(dev, struct_size(cinfo, config, count + 1), GFP_KERNEL);
	if (!cinfo)
		return ERR_PTR(-ENOMEM);

	cinfo->info.type = type;
	cinfo->info.config = cinfo->config;

	for (i = 0; i < count; i++)
		cinfo->config[i] = config;

	return &cinfo->info;
}

static void dell_wmi_ddv_hwmon_cache_invalidate(struct dell_wmi_ddv_sensors *sensors)
{
	if (!sensors->active)
		return;

	mutex_lock(&sensors->lock);
	kfree(sensors->obj);
	sensors->obj = NULL;
	mutex_unlock(&sensors->lock);
}

static void dell_wmi_ddv_hwmon_cache_destroy(void *data)
{
	struct dell_wmi_ddv_sensors *sensors = data;

	sensors->active = false;
	mutex_destroy(&sensors->lock);
	kfree(sensors->obj);
}

static struct hwmon_channel_info *dell_wmi_ddv_channel_init(struct wmi_device *wdev,
							    enum dell_ddv_method method,
							    struct dell_wmi_ddv_sensors *sensors,
							    size_t entry_size,
							    enum hwmon_sensor_types type,
							    u32 config)
{
	struct hwmon_channel_info *info;
	int ret;

	ret = dell_wmi_ddv_update_sensors(wdev, method, sensors, entry_size);
	if (ret < 0)
		return ERR_PTR(ret);

	mutex_init(&sensors->lock);
	sensors->active = true;

	ret = devm_add_action_or_reset(&wdev->dev, dell_wmi_ddv_hwmon_cache_destroy, sensors);
	if (ret < 0)
		return ERR_PTR(ret);

	info = dell_wmi_ddv_channel_create(&wdev->dev, sensors->entries, type, config);
	if (IS_ERR(info))
		devm_release_action(&wdev->dev, dell_wmi_ddv_hwmon_cache_destroy, sensors);

	return info;
}

static int dell_wmi_ddv_hwmon_add(struct dell_wmi_ddv_data *data)
{
	struct wmi_device *wdev = data->wdev;
	struct combined_chip_info *cinfo;
	struct hwmon_channel_info *info;
	struct device *hdev;
	int index = 0;
	int ret;

	if (!devres_open_group(&wdev->dev, dell_wmi_ddv_hwmon_add, GFP_KERNEL))
		return -ENOMEM;

	cinfo = devm_kzalloc(&wdev->dev, struct_size(cinfo, info, 4), GFP_KERNEL);
	if (!cinfo) {
		ret = -ENOMEM;

		goto err_release;
	}

	cinfo->chip.ops = &dell_wmi_ddv_ops;
	cinfo->chip.info = cinfo->info;

	info = dell_wmi_ddv_channel_create(&wdev->dev, 1, hwmon_chip, HWMON_C_REGISTER_TZ);
	if (IS_ERR(info)) {
		ret = PTR_ERR(info);

		goto err_release;
	}

	cinfo->info[index] = info;
	index++;

	info = dell_wmi_ddv_channel_init(wdev, DELL_DDV_FAN_SENSOR_INFORMATION, &data->fans,
					 sizeof(struct fan_sensor_entry), hwmon_fan,
					 (HWMON_F_INPUT | HWMON_F_LABEL));
	if (!IS_ERR(info)) {
		cinfo->info[index] = info;
		index++;
	}

	info = dell_wmi_ddv_channel_init(wdev, DELL_DDV_THERMAL_SENSOR_INFORMATION, &data->temps,
					 sizeof(struct thermal_sensor_entry), hwmon_temp,
					 (HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
					 HWMON_T_LABEL));
	if (!IS_ERR(info)) {
		cinfo->info[index] = info;
		index++;
	}

	if (index < 2) {
		ret = -ENODEV;

		goto err_release;
	}

	hdev = devm_hwmon_device_register_with_info(&wdev->dev, "dell_ddv", data, &cinfo->chip,
						    NULL);
	if (IS_ERR(hdev)) {
		ret = PTR_ERR(hdev);

		goto err_release;
	}

	devres_close_group(&wdev->dev, dell_wmi_ddv_hwmon_add);

	return 0;

err_release:
	devres_release_group(&wdev->dev, dell_wmi_ddv_hwmon_add);

	return ret;
}

static int dell_wmi_ddv_battery_index(struct acpi_device *acpi_dev, u32 *index)
{
	const char *uid_str;

	uid_str = acpi_device_uid(acpi_dev);
	if (!uid_str)
		return -ENODEV;

	return kstrtou32(uid_str, 10, index);
}

static ssize_t temp_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct dell_wmi_ddv_data *data = container_of(attr, struct dell_wmi_ddv_data, temp_attr);
	u32 index, value;
	int ret;

	ret = dell_wmi_ddv_battery_index(to_acpi_device(dev->parent), &index);
	if (ret < 0)
		return ret;

	ret = dell_wmi_ddv_query_integer(data->wdev, DELL_DDV_BATTERY_TEMPERATURE, index, &value);
	if (ret < 0)
		return ret;

	/* Use 2731 instead of 2731.5 to avoid unnecessary rounding */
	return sysfs_emit(buf, "%d\n", value - 2731);
}

static ssize_t eppid_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct dell_wmi_ddv_data *data = container_of(attr, struct dell_wmi_ddv_data, eppid_attr);
	union acpi_object *obj;
	u32 index;
	int ret;

	ret = dell_wmi_ddv_battery_index(to_acpi_device(dev->parent), &index);
	if (ret < 0)
		return ret;

	ret = dell_wmi_ddv_query_string(data->wdev, DELL_DDV_BATTERY_EPPID, index, &obj);
	if (ret < 0)
		return ret;

	if (obj->string.length != DELL_EPPID_LENGTH && obj->string.length != DELL_EPPID_EXT_LENGTH)
		dev_info_once(&data->wdev->dev, FW_INFO "Suspicious ePPID length (%d)\n",
			      obj->string.length);

	ret = sysfs_emit(buf, "%s\n", obj->string.pointer);

	kfree(obj);

	return ret;
}

static int dell_wmi_ddv_add_battery(struct power_supply *battery, struct acpi_battery_hook *hook)
{
	struct dell_wmi_ddv_data *data = container_of(hook, struct dell_wmi_ddv_data, hook);
	u32 index;
	int ret;

	/* Return 0 instead of error to avoid being unloaded */
	ret = dell_wmi_ddv_battery_index(to_acpi_device(battery->dev.parent), &index);
	if (ret < 0)
		return 0;

	ret = device_create_file(&battery->dev, &data->temp_attr);
	if (ret < 0)
		return ret;

	ret = device_create_file(&battery->dev, &data->eppid_attr);
	if (ret < 0) {
		device_remove_file(&battery->dev, &data->temp_attr);

		return ret;
	}

	return 0;
}

static int dell_wmi_ddv_remove_battery(struct power_supply *battery, struct acpi_battery_hook *hook)
{
	struct dell_wmi_ddv_data *data = container_of(hook, struct dell_wmi_ddv_data, hook);

	device_remove_file(&battery->dev, &data->temp_attr);
	device_remove_file(&battery->dev, &data->eppid_attr);

	return 0;
}

static void dell_wmi_ddv_battery_remove(void *data)
{
	struct acpi_battery_hook *hook = data;

	battery_hook_unregister(hook);
}

static int dell_wmi_ddv_battery_add(struct dell_wmi_ddv_data *data)
{
	data->hook.name = "Dell DDV Battery Extension";
	data->hook.add_battery = dell_wmi_ddv_add_battery;
	data->hook.remove_battery = dell_wmi_ddv_remove_battery;

	sysfs_attr_init(&data->temp_attr.attr);
	data->temp_attr.attr.name = "temp";
	data->temp_attr.attr.mode = 0444;
	data->temp_attr.show = temp_show;

	sysfs_attr_init(&data->eppid_attr.attr);
	data->eppid_attr.attr.name = "eppid";
	data->eppid_attr.attr.mode = 0444;
	data->eppid_attr.show = eppid_show;

	battery_hook_register(&data->hook);

	return devm_add_action_or_reset(&data->wdev->dev, dell_wmi_ddv_battery_remove, &data->hook);
}

static int dell_wmi_ddv_buffer_read(struct seq_file *seq, enum dell_ddv_method method)
{
	struct device *dev = seq->private;
	struct dell_wmi_ddv_data *data = dev_get_drvdata(dev);
	union acpi_object *obj;
	u64 size;
	u8 *buf;
	int ret;

	ret = dell_wmi_ddv_query_buffer(data->wdev, method, 0, &obj);
	if (ret < 0)
		return ret;

	size = obj->package.elements[0].integer.value;
	buf = obj->package.elements[1].buffer.pointer;
	ret = seq_write(seq, buf, size);
	kfree(obj);

	return ret;
}

static int dell_wmi_ddv_fan_read(struct seq_file *seq, void *offset)
{
	return dell_wmi_ddv_buffer_read(seq, DELL_DDV_FAN_SENSOR_INFORMATION);
}

static int dell_wmi_ddv_temp_read(struct seq_file *seq, void *offset)
{
	return dell_wmi_ddv_buffer_read(seq, DELL_DDV_THERMAL_SENSOR_INFORMATION);
}

static void dell_wmi_ddv_debugfs_remove(void *data)
{
	struct dentry *entry = data;

	debugfs_remove(entry);
}

static void dell_wmi_ddv_debugfs_init(struct wmi_device *wdev)
{
	struct dentry *entry;
	char name[64];

	scnprintf(name, ARRAY_SIZE(name), "%s-%s", DRIVER_NAME, dev_name(&wdev->dev));
	entry = debugfs_create_dir(name, NULL);

	debugfs_create_devm_seqfile(&wdev->dev, "fan_sensor_information", entry,
				    dell_wmi_ddv_fan_read);
	debugfs_create_devm_seqfile(&wdev->dev, "thermal_sensor_information", entry,
				    dell_wmi_ddv_temp_read);

	devm_add_action_or_reset(&wdev->dev, dell_wmi_ddv_debugfs_remove, entry);
}

static int dell_wmi_ddv_probe(struct wmi_device *wdev, const void *context)
{
	struct dell_wmi_ddv_data *data;
	u32 version;
	int ret;

	ret = dell_wmi_ddv_query_integer(wdev, DELL_DDV_INTERFACE_VERSION, 0, &version);
	if (ret < 0)
		return ret;

	dev_dbg(&wdev->dev, "WMI interface version: %d\n", version);
	if (version < DELL_DDV_SUPPORTED_VERSION_MIN || version > DELL_DDV_SUPPORTED_VERSION_MAX) {
		if (!force)
			return -ENODEV;

		dev_warn(&wdev->dev, "Loading despite unsupported WMI interface version (%u)\n",
			 version);
	}

	data = devm_kzalloc(&wdev->dev, sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	dev_set_drvdata(&wdev->dev, data);
	data->wdev = wdev;

	dell_wmi_ddv_debugfs_init(wdev);

	if (IS_REACHABLE(CONFIG_ACPI_BATTERY)) {
		ret = dell_wmi_ddv_battery_add(data);
		if (ret < 0 && ret != -ENODEV)
			dev_warn(&wdev->dev, "Unable to register ACPI battery hook: %d\n", ret);
	}

	if (IS_REACHABLE(CONFIG_HWMON)) {
		ret = dell_wmi_ddv_hwmon_add(data);
		if (ret < 0 && ret != -ENODEV)
			dev_warn(&wdev->dev, "Unable to register hwmon interface: %d\n", ret);
	}

	return 0;
}

static int dell_wmi_ddv_resume(struct device *dev)
{
	struct dell_wmi_ddv_data *data = dev_get_drvdata(dev);

	/* Force re-reading of all active sensors */
	dell_wmi_ddv_hwmon_cache_invalidate(&data->fans);
	dell_wmi_ddv_hwmon_cache_invalidate(&data->temps);

	return 0;
}

static DEFINE_SIMPLE_DEV_PM_OPS(dell_wmi_ddv_dev_pm_ops, NULL, dell_wmi_ddv_resume);

static const struct wmi_device_id dell_wmi_ddv_id_table[] = {
	{ DELL_DDV_GUID, NULL },
	{ }
};
MODULE_DEVICE_TABLE(wmi, dell_wmi_ddv_id_table);

static struct wmi_driver dell_wmi_ddv_driver = {
	.driver = {
		.name = DRIVER_NAME,
		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
		.pm = pm_sleep_ptr(&dell_wmi_ddv_dev_pm_ops),
	},
	.id_table = dell_wmi_ddv_id_table,
	.probe = dell_wmi_ddv_probe,
};
module_wmi_driver(dell_wmi_ddv_driver);

MODULE_AUTHOR("Armin Wolf <W_Armin@gmx.de>");
MODULE_DESCRIPTION("Dell WMI sensor driver");
MODULE_LICENSE("GPL");
