// 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 **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));
		strlcpy(fn_type, fn_item, fn_item_len - 5);
		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));

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

			if (read_len > 0)
				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("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));

			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 += snprintf(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;

		len = snprintf(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 = snprintf(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), 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;
}
