// 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) {
		/* Finding no available sensors is not an error */
		ret = 0;

		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)
			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)
			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");
