// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
#include "counts.h"
#include "debug.h"
#include "evsel.h"
#include "hashmap.h"
#include "hwmon_pmu.h"
#include "pmu.h"
#include <internal/xyarray.h>
#include <internal/threadmap.h>
#include <perf/threadmap.h>
#include <sys/types.h>
#include <assert.h>
#include <ctype.h>
#include <fcntl.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <api/fs/fs.h>
#include <api/io.h>
#include <api/io_dir.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/zalloc.h>

/** Strings that correspond to enum hwmon_type. */
static const char * const hwmon_type_strs[HWMON_TYPE_MAX] = {
	NULL,
	"cpu",
	"curr",
	"energy",
	"fan",
	"humidity",
	"in",
	"intrusion",
	"power",
	"pwm",
	"temp",
};
#define LONGEST_HWMON_TYPE_STR "intrusion"

/** Strings that correspond to enum hwmon_item. */
static const char * const hwmon_item_strs[HWMON_ITEM__MAX] = {
	NULL,
	"accuracy",
	"alarm",
	"auto_channels_temp",
	"average",
	"average_highest",
	"average_interval",
	"average_interval_max",
	"average_interval_min",
	"average_lowest",
	"average_max",
	"average_min",
	"beep",
	"cap",
	"cap_hyst",
	"cap_max",
	"cap_min",
	"crit",
	"crit_hyst",
	"div",
	"emergency",
	"emergency_hist",
	"enable",
	"fault",
	"freq",
	"highest",
	"input",
	"label",
	"lcrit",
	"lcrit_hyst",
	"lowest",
	"max",
	"max_hyst",
	"min",
	"min_hyst",
	"mod",
	"offset",
	"pulses",
	"rated_max",
	"rated_min",
	"reset_history",
	"target",
	"type",
	"vid",
};
#define LONGEST_HWMON_ITEM_STR "average_interval_max"

static const char *const hwmon_units[HWMON_TYPE_MAX] = {
	NULL,
	"V",   /* cpu */
	"A",   /* curr */
	"J",   /* energy */
	"rpm", /* fan */
	"%",   /* humidity */
	"V",   /* in */
	"",    /* intrusion */
	"W",   /* power */
	"Hz",  /* pwm */
	"'C",  /* temp */
};

struct hwmon_pmu {
	struct perf_pmu pmu;
	struct hashmap events;
	char *hwmon_dir;
};

/**
 * struct hwmon_pmu_event_value: Value in hwmon_pmu->events.
 *
 * Hwmon files are of the form <type><number>_<item> and may have a suffix
 * _alarm.
 */
struct hwmon_pmu_event_value {
	/** @items: which item files are present. */
	DECLARE_BITMAP(items, HWMON_ITEM__MAX);
	/** @alarm_items: which item files are present. */
	DECLARE_BITMAP(alarm_items, HWMON_ITEM__MAX);
	/** @label: contents of <type><number>_label if present. */
	char *label;
	/** @name: name computed from label of the form <type>_<label>. */
	char *name;
};

bool perf_pmu__is_hwmon(const struct perf_pmu *pmu)
{
	return pmu && pmu->type >= PERF_PMU_TYPE_HWMON_START &&
		pmu->type <= PERF_PMU_TYPE_HWMON_END;
}

bool evsel__is_hwmon(const struct evsel *evsel)
{
	return perf_pmu__is_hwmon(evsel->pmu);
}

static size_t hwmon_pmu__event_hashmap_hash(long key, void *ctx __maybe_unused)
{
	return ((union hwmon_pmu_event_key)key).type_and_num;
}

static bool hwmon_pmu__event_hashmap_equal(long key1, long key2, void *ctx __maybe_unused)
{
	return ((union hwmon_pmu_event_key)key1).type_and_num ==
	       ((union hwmon_pmu_event_key)key2).type_and_num;
}

static int hwmon_strcmp(const void *a, const void *b)
{
	const char *sa = a;
	const char * const *sb = b;

	return strcmp(sa, *sb);
}

bool parse_hwmon_filename(const char *filename,
			  enum hwmon_type *type,
			  int *number,
			  enum hwmon_item *item,
			  bool *alarm)
{
	char fn_type[24];
	const char * const *elem;
	const char *fn_item = NULL;
	size_t fn_item_len;

	assert(strlen(LONGEST_HWMON_TYPE_STR) < sizeof(fn_type));
	strlcpy(fn_type, filename, sizeof(fn_type));
	for (size_t i = 0; fn_type[i] != '\0'; i++) {
		if (fn_type[i] >= '0' && fn_type[i] <= '9') {
			fn_type[i] = '\0';
			*number = strtoul(&filename[i], (char **)&fn_item, 10);
			if (*fn_item == '_')
				fn_item++;
			break;
		}
		if (fn_type[i] == '_') {
			fn_type[i] = '\0';
			*number = -1;
			fn_item = &filename[i + 1];
			break;
		}
	}
	if (fn_item == NULL || fn_type[0] == '\0' || (item != NULL && fn_item[0] == '\0')) {
		pr_debug3("hwmon_pmu: not a hwmon file '%s'\n", filename);
		return false;
	}
	elem = bsearch(&fn_type, hwmon_type_strs + 1, ARRAY_SIZE(hwmon_type_strs) - 1,
		       sizeof(hwmon_type_strs[0]), hwmon_strcmp);
	if (!elem) {
		pr_debug3("hwmon_pmu: not a hwmon type '%s' in file name '%s'\n",
			 fn_type, filename);
		return false;
	}

	*type = elem - &hwmon_type_strs[0];
	if (!item)
		return true;

	*alarm = false;
	fn_item_len = strlen(fn_item);
	if (fn_item_len > 6 && !strcmp(&fn_item[fn_item_len - 6], "_alarm")) {
		assert(strlen(LONGEST_HWMON_ITEM_STR) < sizeof(fn_type));
		/* fn_item_len - 5 strips "_alarm"; clamp to buffer size */
		strlcpy(fn_type, fn_item, min_t(size_t, fn_item_len - 5, sizeof(fn_type)));
		fn_item = fn_type;
		*alarm = true;
	}
	elem = bsearch(fn_item, hwmon_item_strs + 1, ARRAY_SIZE(hwmon_item_strs) - 1,
		       sizeof(hwmon_item_strs[0]), hwmon_strcmp);
	if (!elem) {
		pr_debug3("hwmon_pmu: not a hwmon item '%s' in file name '%s'\n",
			 fn_item, filename);
		return false;
	}
	*item = elem - &hwmon_item_strs[0];
	return true;
}

static void fix_name(char *p)
{
	char *s = strchr(p, '\n');

	if (s)
		*s = '\0';

	while (*p != '\0') {
		if (strchr(" :,/\n\t", *p))
			*p = '_';
		else
			*p = tolower(*p);
		p++;
	}
}

static int hwmon_pmu__read_events(struct hwmon_pmu *pmu)
{
	int err = 0;
	struct hashmap_entry *cur, *tmp;
	size_t bkt;
	struct io_dirent64 *ent;
	struct io_dir dir;

	if (pmu->pmu.sysfs_aliases_loaded)
		return 0;

	/* Use openat so that the directory contents are refreshed. */
	io_dir__init(&dir, open(pmu->hwmon_dir, O_CLOEXEC | O_DIRECTORY | O_RDONLY));

	if (dir.dirfd < 0)
		return -ENOENT;

	while ((ent = io_dir__readdir(&dir)) != NULL) {
		enum hwmon_type type;
		int number;
		enum hwmon_item item;
		bool alarm;
		union hwmon_pmu_event_key key = { .type_and_num = 0 };
		struct hwmon_pmu_event_value *value;

		if (ent->d_type != DT_REG)
			continue;

		if (!parse_hwmon_filename(ent->d_name, &type, &number, &item, &alarm)) {
			pr_debug3("Not a hwmon file '%s'\n", ent->d_name);
			continue;
		}
		key.num = number;
		key.type = type;
		if (!hashmap__find(&pmu->events, key.type_and_num, &value)) {
			value = zalloc(sizeof(*value));
			if (!value) {
				err = -ENOMEM;
				goto err_out;
			}
			err = hashmap__add(&pmu->events, key.type_and_num, value);
			if (err) {
				free(value);
				err = -ENOMEM;
				goto err_out;
			}
		}
		__set_bit(item, alarm ? value->alarm_items : value->items);
		if (item == HWMON_ITEM_LABEL) {
			char buf[128];
			int fd = openat(dir.dirfd, ent->d_name, O_RDONLY);
			ssize_t read_len;

			if (fd < 0)
				continue;

			read_len = read(fd, buf, sizeof(buf) - 1);

			while (read_len > 0 && buf[read_len - 1] == '\n')
				read_len--;

			if (read_len <= 0) {
				close(fd);
				continue;
			}
			buf[read_len] = '\0';

			if (buf[0] == '\0') {
				pr_debug("hwmon_pmu: empty label file %s %s\n",
					 pmu->pmu.name, ent->d_name);
				close(fd);
				continue;
			}
			value->label = strdup(buf);
			if (!value->label) {
				pr_debug("hwmon_pmu: memory allocation failure\n");
				close(fd);
				continue;
			}
			snprintf(buf, sizeof(buf), "%s_%s", hwmon_type_strs[type], value->label);
			fix_name(buf);
			value->name = strdup(buf);
			if (!value->name)
				pr_debug("hwmon_pmu: memory allocation failure\n");
			close(fd);
		}
	}
	if (hashmap__size(&pmu->events) == 0)
		pr_debug2("hwmon_pmu: %s has no events\n", pmu->pmu.name);

	hashmap__for_each_entry_safe((&pmu->events), cur, tmp, bkt) {
		union hwmon_pmu_event_key key = {
			.type_and_num = cur->key,
		};
		struct hwmon_pmu_event_value *value = cur->pvalue;

		if (!test_bit(HWMON_ITEM_INPUT, value->items)) {
			pr_debug("hwmon_pmu: %s removing event '%s%d' that has no input file\n",
				pmu->pmu.name, hwmon_type_strs[key.type], key.num);
			hashmap__delete(&pmu->events, key.type_and_num, &key, &value);
			zfree(&value->label);
			zfree(&value->name);
			free(value);
		}
	}
	pmu->pmu.sysfs_aliases_loaded = true;

err_out:
	close(dir.dirfd);
	return err;
}

struct perf_pmu *hwmon_pmu__new(struct list_head *pmus, const char *hwmon_dir,
				const char *sysfs_name, const char *name)
{
	char buf[64];
	struct hwmon_pmu *hwm;
	__u32 type = PERF_PMU_TYPE_HWMON_START + strtoul(sysfs_name + 5, NULL, 10);

	if (type > PERF_PMU_TYPE_HWMON_END) {
		pr_err("Unable to encode hwmon type from %s in valid PMU type\n", sysfs_name);
		return NULL;
	}

	snprintf(buf, sizeof(buf), "hwmon_%s", name);
	fix_name(buf + 6);

	hwm = zalloc(sizeof(*hwm));
	if (!hwm)
		return NULL;

	if (perf_pmu__init(&hwm->pmu, type, buf) != 0) {
		perf_pmu__delete(&hwm->pmu);
		return NULL;
	}

	hwm->hwmon_dir = strdup(hwmon_dir);
	if (!hwm->hwmon_dir) {
		perf_pmu__delete(&hwm->pmu);
		return NULL;
	}
	hwm->pmu.alias_name = strdup(sysfs_name);
	if (!hwm->pmu.alias_name) {
		perf_pmu__delete(&hwm->pmu);
		return NULL;
	}
	hwm->pmu.cpus = perf_cpu_map__new_int(0);
	if (!hwm->pmu.cpus) {
		perf_pmu__delete(&hwm->pmu);
		return NULL;
	}
	INIT_LIST_HEAD(&hwm->pmu.format);
	INIT_LIST_HEAD(&hwm->pmu.caps);
	hashmap__init(&hwm->events, hwmon_pmu__event_hashmap_hash,
		      hwmon_pmu__event_hashmap_equal, /*ctx=*/NULL);

	list_add_tail(&hwm->pmu.list, pmus);
	return &hwm->pmu;
}

void hwmon_pmu__exit(struct perf_pmu *pmu)
{
	struct hwmon_pmu *hwm = container_of(pmu, struct hwmon_pmu, pmu);
	struct hashmap_entry *cur, *tmp;
	size_t bkt;

	hashmap__for_each_entry_safe((&hwm->events), cur, tmp, bkt) {
		struct hwmon_pmu_event_value *value = cur->pvalue;

		zfree(&value->label);
		zfree(&value->name);
		free(value);
	}
	hashmap__clear(&hwm->events);
	zfree(&hwm->hwmon_dir);
}

static size_t hwmon_pmu__describe_items(struct hwmon_pmu *hwm, char *out_buf, size_t out_buf_len,
					union hwmon_pmu_event_key key,
					const unsigned long *items, bool is_alarm)
{
	size_t bit;
	char buf[64];
	size_t len = 0;
	int dir = open(hwm->hwmon_dir, O_CLOEXEC | O_DIRECTORY | O_RDONLY);

	if (dir < 0)
		return 0;

	for_each_set_bit(bit, items, HWMON_ITEM__MAX) {
		int fd;

		if (bit == HWMON_ITEM_LABEL || bit == HWMON_ITEM_INPUT)
			continue;

		snprintf(buf, sizeof(buf), "%s%d_%s%s",
			hwmon_type_strs[key.type],
			key.num,
			hwmon_item_strs[bit],
			is_alarm ? "_alarm" : "");
		fd = openat(dir, buf, O_RDONLY);
		if (fd >= 0) {
			ssize_t read_len = read(fd, buf, sizeof(buf) - 1);

			while (read_len > 0 && buf[read_len - 1] == '\n')
				read_len--;

			if (read_len > 0) {
				long long val;

				buf[read_len] = '\0';
				val = strtoll(buf, /*endptr=*/NULL, 10);
				len += scnprintf(out_buf + len, out_buf_len - len, "%s%s%s=%g%s",
						 len == 0 ? " " : ", ",
						 hwmon_item_strs[bit],
						 is_alarm ? "_alarm" : "",
						 (double)val / 1000.0,
						 hwmon_units[key.type]);
			}
			close(fd);
		}
	}
	close(dir);
	return len;
}

int hwmon_pmu__for_each_event(struct perf_pmu *pmu, void *state, pmu_event_callback cb)
{
	struct hwmon_pmu *hwm = container_of(pmu, struct hwmon_pmu, pmu);
	struct hashmap_entry *cur;
	size_t bkt;

	if (hwmon_pmu__read_events(hwm))
		return false;

	hashmap__for_each_entry((&hwm->events), cur, bkt) {
		static const char *const hwmon_scale_units[HWMON_TYPE_MAX] = {
			NULL,
			"0.001V", /* cpu */
			"0.001A", /* curr */
			"0.001J", /* energy */
			"1rpm",   /* fan */
			"0.001%", /* humidity */
			"0.001V", /* in */
			NULL,     /* intrusion */
			"0.001W", /* power */
			"1Hz",    /* pwm */
			"0.001'C", /* temp */
		};
		static const char *const hwmon_desc[HWMON_TYPE_MAX] = {
			NULL,
			"CPU core reference voltage",   /* cpu */
			"Current",                      /* curr */
			"Cumulative energy use",        /* energy */
			"Fan",                          /* fan */
			"Humidity",                     /* humidity */
			"Voltage",                      /* in */
			"Chassis intrusion detection",  /* intrusion */
			"Power use",                    /* power */
			"Pulse width modulation fan control", /* pwm */
			"Temperature",                  /* temp */
		};
		char alias_buf[64];
		char desc_buf[256];
		char encoding_buf[128];
		union hwmon_pmu_event_key key = {
			.type_and_num = cur->key,
		};
		struct hwmon_pmu_event_value *value = cur->pvalue;
		struct pmu_event_info info = {
			.pmu = pmu,
			.name = value->name,
			.alias = alias_buf,
			.scale_unit = hwmon_scale_units[key.type],
			.desc = desc_buf,
			.long_desc = NULL,
			.encoding_desc = encoding_buf,
			.topic = "hwmon",
			.pmu_name = pmu->name,
			.event_type_desc = "Hwmon event",
		};
		int ret;
		size_t len;

		scnprintf(alias_buf, sizeof(alias_buf), "%s%d",
			  hwmon_type_strs[key.type], key.num);
		if (!info.name) {
			info.name = info.alias;
			info.alias = NULL;
		}

		len = scnprintf(desc_buf, sizeof(desc_buf), "%s in unit %s named %s.",
			hwmon_desc[key.type],
			pmu->name + 6,
			value->label ?: info.name);

		len += hwmon_pmu__describe_items(hwm, desc_buf + len, sizeof(desc_buf) - len,
						key, value->items, /*is_alarm=*/false);

		len += hwmon_pmu__describe_items(hwm, desc_buf + len, sizeof(desc_buf) - len,
						key, value->alarm_items, /*is_alarm=*/true);

		snprintf(encoding_buf, sizeof(encoding_buf), "%s/config=0x%lx/",
			 pmu->name, cur->key);

		ret = cb(state, &info);
		if (ret)
			return ret;
	}
	return 0;
}

size_t hwmon_pmu__num_events(struct perf_pmu *pmu)
{
	struct hwmon_pmu *hwm = container_of(pmu, struct hwmon_pmu, pmu);

	hwmon_pmu__read_events(hwm);
	return hashmap__size(&hwm->events);
}

bool hwmon_pmu__have_event(struct perf_pmu *pmu, const char *name)
{
	struct hwmon_pmu *hwm = container_of(pmu, struct hwmon_pmu, pmu);
	enum hwmon_type type;
	int number;
	union hwmon_pmu_event_key key = { .type_and_num = 0 };
	struct hashmap_entry *cur;
	size_t bkt;

	if (!parse_hwmon_filename(name, &type, &number, /*item=*/NULL, /*is_alarm=*/NULL))
		return false;

	if (hwmon_pmu__read_events(hwm))
		return false;

	key.type = type;
	key.num = number;
	if (hashmap_find(&hwm->events, key.type_and_num, /*value=*/NULL))
		return true;
	if (key.num != -1)
		return false;
	/* Item is of form <type>_ which means we should match <type>_<label>. */
	hashmap__for_each_entry((&hwm->events), cur, bkt) {
		struct hwmon_pmu_event_value *value = cur->pvalue;

		key.type_and_num = cur->key;
		if (key.type == type && value->name && !strcasecmp(name, value->name))
			return true;
	}
	return false;
}

static int hwmon_pmu__config_term(const struct hwmon_pmu *hwm,
				  struct perf_event_attr *attr,
				  struct parse_events_term *term,
				  struct parse_events_error *err)
{
	if (term->type_term == PARSE_EVENTS__TERM_TYPE_USER) {
		enum hwmon_type type;
		int number;

		if (parse_hwmon_filename(term->config, &type, &number,
					 /*item=*/NULL, /*is_alarm=*/NULL)) {
			if (number == -1) {
				/*
				 * Item is of form <type>_ which means we should
				 * match <type>_<label>.
				 */
				struct hashmap_entry *cur;
				size_t bkt;

				attr->config = 0;
				hashmap__for_each_entry((&hwm->events), cur, bkt) {
					union hwmon_pmu_event_key key = {
						.type_and_num = cur->key,
					};
					struct hwmon_pmu_event_value *value = cur->pvalue;

					if (key.type == type && value->name &&
					    !strcasecmp(term->config, value->name)) {
						attr->config = key.type_and_num;
						break;
					}
				}
				if (attr->config == 0)
					return -EINVAL;
			} else {
				union hwmon_pmu_event_key key = {
					.type_and_num = 0,
				};

				key.type = type;
				key.num = number;
				attr->config = key.type_and_num;
			}
			return 0;
		}
	}
	if (err) {
		char *err_str;

		parse_events_error__handle(err, term->err_val,
					asprintf(&err_str,
						"unexpected hwmon event term (%s) %s",
						parse_events__term_type_str(term->type_term),
						term->config) < 0
					? strdup("unexpected hwmon event term")
					: err_str,
					NULL);
	}
	return -EINVAL;
}

int hwmon_pmu__config_terms(const struct perf_pmu *pmu,
			    struct perf_event_attr *attr,
			    struct parse_events_terms *terms,
			    struct parse_events_error *err)
{
	struct hwmon_pmu *hwm = container_of(pmu, struct hwmon_pmu, pmu);
	struct parse_events_term *term;
	int ret;

	ret = hwmon_pmu__read_events(hwm);
	if (ret)
		return ret;

	list_for_each_entry(term, &terms->terms, list) {
		if (hwmon_pmu__config_term(hwm, attr, term, err))
			return -EINVAL;
	}

	return 0;

}

int hwmon_pmu__check_alias(struct parse_events_terms *terms, struct perf_pmu_info *info,
			   struct parse_events_error *err)
{
	struct parse_events_term *term =
		list_first_entry(&terms->terms, struct parse_events_term, list);

	if (term->type_term == PARSE_EVENTS__TERM_TYPE_USER) {
		enum hwmon_type type;
		int number;

		if (parse_hwmon_filename(term->config, &type, &number,
					 /*item=*/NULL, /*is_alarm=*/NULL)) {
			info->unit = hwmon_units[type];
			if (type == HWMON_TYPE_FAN || type == HWMON_TYPE_PWM ||
			    type == HWMON_TYPE_INTRUSION)
				info->scale = 1;
			else
				info->scale = 0.001;
		}
		return 0;
	}
	if (err) {
		char *err_str;

		parse_events_error__handle(err, term->err_val,
					asprintf(&err_str,
						"unexpected hwmon event term (%s) %s",
						parse_events__term_type_str(term->type_term),
						term->config) < 0
					? strdup("unexpected hwmon event term")
					: err_str,
					NULL);
	}
	return -EINVAL;
}

int perf_pmus__read_hwmon_pmus(struct list_head *pmus)
{
	char *line = NULL;
	struct io_dirent64 *class_hwmon_ent;
	struct io_dir class_hwmon_dir;
	char buf[PATH_MAX];
	const char *sysfs = sysfs__mountpoint();

	if (!sysfs)
		return 0;

	scnprintf(buf, sizeof(buf), "%s/class/hwmon/", sysfs);
	io_dir__init(&class_hwmon_dir, open(buf, O_CLOEXEC | O_DIRECTORY | O_RDONLY));

	if (class_hwmon_dir.dirfd < 0)
		return 0;

	while ((class_hwmon_ent = io_dir__readdir(&class_hwmon_dir)) != NULL) {
		size_t line_len;
		int hwmon_dir, name_fd;
		struct io io;
		char buf2[128];

		if (class_hwmon_ent->d_type != DT_LNK)
			continue;

		scnprintf(buf, sizeof(buf), "%s/class/hwmon/%s", sysfs, class_hwmon_ent->d_name);
		hwmon_dir = open(buf, O_DIRECTORY);
		if (hwmon_dir == -1) {
			pr_debug("hwmon_pmu: not a directory: '%s/class/hwmon/%s'\n",
				 sysfs, class_hwmon_ent->d_name);
			continue;
		}
		name_fd = openat(hwmon_dir, "name", O_RDONLY);
		if (name_fd == -1) {
			pr_debug("hwmon_pmu: failure to open '%s/class/hwmon/%s/name'\n",
				  sysfs, class_hwmon_ent->d_name);
			close(hwmon_dir);
			continue;
		}
		io__init(&io, name_fd, buf2, sizeof(buf2));
		if (io__getline(&io, &line, &line_len) > 0 && line[line_len - 1] == '\n')
			line[line_len - 1] = '\0';
		hwmon_pmu__new(pmus, buf, class_hwmon_ent->d_name, line);
		close(name_fd);
		close(hwmon_dir);
	}
	free(line);
	close(class_hwmon_dir.dirfd);
	return 0;
}

#define FD(e, x, y) (*(int *)xyarray__entry(e->core.fd, x, y))

int evsel__hwmon_pmu_open(struct evsel *evsel,
			  struct perf_thread_map *threads,
			  int start_cpu_map_idx, int end_cpu_map_idx)
{
	struct hwmon_pmu *hwm = container_of(evsel->pmu, struct hwmon_pmu, pmu);
	union hwmon_pmu_event_key key = {
		.type_and_num = evsel->core.attr.config,
	};
	int idx = 0, thread = 0, nthreads, err = 0;
	int dir = open(hwm->hwmon_dir, O_CLOEXEC | O_DIRECTORY | O_RDONLY);

	if (dir < 0)
		return -errno;

	nthreads = perf_thread_map__nr(threads);
	for (idx = start_cpu_map_idx; idx < end_cpu_map_idx; idx++) {
		for (thread = 0; thread < nthreads; thread++) {
			char buf[64];
			int fd;

			snprintf(buf, sizeof(buf), "%s%d_input",
				 hwmon_type_strs[key.type], key.num);

			fd = openat(dir, buf, O_RDONLY);
			FD(evsel, idx, thread) = fd;
			if (fd < 0) {
				err = -errno;
				goto out_close;
			}
		}
	}
	close(dir);
	return 0;
out_close:
	if (err)
		threads->err_thread = thread;

	do {
		while (--thread >= 0) {
			if (FD(evsel, idx, thread) >= 0)
				close(FD(evsel, idx, thread));
			FD(evsel, idx, thread) = -1;
		}
		thread = nthreads;
	} while (--idx >= 0);
	close(dir);
	return err;
}

int evsel__hwmon_pmu_read(struct evsel *evsel, int cpu_map_idx, int thread)
{
	char buf[32];
	int fd;
	ssize_t len;
	struct perf_counts_values *count, *old_count = NULL;

	if (evsel->prev_raw_counts)
		old_count = perf_counts(evsel->prev_raw_counts, cpu_map_idx, thread);

	count = perf_counts(evsel->counts, cpu_map_idx, thread);
	fd = FD(evsel, cpu_map_idx, thread);
	len = pread(fd, buf, sizeof(buf) - 1, 0);
	if (len <= 0) {
		count->lost++;
		return -EINVAL;
	}
	buf[len] = '\0';
	if (old_count) {
		count->val = old_count->val + strtoll(buf, NULL, 10);
		count->run = old_count->run + 1;
		count->ena = old_count->ena + 1;
	} else {
		count->val = strtoll(buf, NULL, 10);
		count->run++;
		count->ena++;
	}
	return 0;
}
