// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * PowerNV OPAL Powercap interface
 *
 * Copyright 2017 IBM Corp.
 */

#define pr_fmt(fmt)     "opal-powercap: " fmt

#include <linux/of.h>
#include <linux/kobject.h>
#include <linux/slab.h>

#include <asm/opal.h>

static DEFINE_MUTEX(powercap_mutex);

static struct kobject *powercap_kobj;

struct powercap_attr {
	u32 handle;
	struct kobj_attribute attr;
};

static struct pcap {
	struct attribute_group pg;
	struct powercap_attr *pattrs;
} *pcaps;

static ssize_t powercap_show(struct kobject *kobj, struct kobj_attribute *attr,
			     char *buf)
{
	struct powercap_attr *pcap_attr = container_of(attr,
						struct powercap_attr, attr);
	struct opal_msg msg;
	u32 pcap;
	int ret, token;

	token = opal_async_get_token_interruptible();
	if (token < 0) {
		pr_devel("Failed to get token\n");
		return token;
	}

	ret = mutex_lock_interruptible(&powercap_mutex);
	if (ret)
		goto out_token;

	ret = opal_get_powercap(pcap_attr->handle, token, (u32 *)__pa(&pcap));
	switch (ret) {
	case OPAL_ASYNC_COMPLETION:
		ret = opal_async_wait_response(token, &msg);
		if (ret) {
			pr_devel("Failed to wait for the async response\n");
			ret = -EIO;
			goto out;
		}
		ret = opal_error_code(opal_get_async_rc(msg));
		if (!ret) {
			ret = sprintf(buf, "%u\n", be32_to_cpu(pcap));
			if (ret < 0)
				ret = -EIO;
		}
		break;
	case OPAL_SUCCESS:
		ret = sprintf(buf, "%u\n", be32_to_cpu(pcap));
		if (ret < 0)
			ret = -EIO;
		break;
	default:
		ret = opal_error_code(ret);
	}

out:
	mutex_unlock(&powercap_mutex);
out_token:
	opal_async_release_token(token);
	return ret;
}

static ssize_t powercap_store(struct kobject *kobj,
			      struct kobj_attribute *attr, const char *buf,
			      size_t count)
{
	struct powercap_attr *pcap_attr = container_of(attr,
						struct powercap_attr, attr);
	struct opal_msg msg;
	u32 pcap;
	int ret, token;

	ret = kstrtoint(buf, 0, &pcap);
	if (ret)
		return ret;

	token = opal_async_get_token_interruptible();
	if (token < 0) {
		pr_devel("Failed to get token\n");
		return token;
	}

	ret = mutex_lock_interruptible(&powercap_mutex);
	if (ret)
		goto out_token;

	ret = opal_set_powercap(pcap_attr->handle, token, pcap);
	switch (ret) {
	case OPAL_ASYNC_COMPLETION:
		ret = opal_async_wait_response(token, &msg);
		if (ret) {
			pr_devel("Failed to wait for the async response\n");
			ret = -EIO;
			goto out;
		}
		ret = opal_error_code(opal_get_async_rc(msg));
		if (!ret)
			ret = count;
		break;
	case OPAL_SUCCESS:
		ret = count;
		break;
	default:
		ret = opal_error_code(ret);
	}

out:
	mutex_unlock(&powercap_mutex);
out_token:
	opal_async_release_token(token);
	return ret;
}

static void powercap_add_attr(int handle, const char *name,
			      struct powercap_attr *attr)
{
	attr->handle = handle;
	sysfs_attr_init(&attr->attr.attr);
	attr->attr.attr.name = name;
	attr->attr.attr.mode = 0444;
	attr->attr.show = powercap_show;
}

void __init opal_powercap_init(void)
{
	struct device_node *powercap, *node;
	int i = 0;

	powercap = of_find_compatible_node(NULL, NULL, "ibm,opal-powercap");
	if (!powercap) {
		pr_devel("Powercap node not found\n");
		return;
	}

	pcaps = kcalloc(of_get_child_count(powercap), sizeof(*pcaps),
			GFP_KERNEL);
	if (!pcaps)
		return;

	powercap_kobj = kobject_create_and_add("powercap", opal_kobj);
	if (!powercap_kobj) {
		pr_warn("Failed to create powercap kobject\n");
		goto out_pcaps;
	}

	i = 0;
	for_each_child_of_node(powercap, node) {
		u32 cur, min, max;
		int j = 0;
		bool has_cur = false, has_min = false, has_max = false;

		if (!of_property_read_u32(node, "powercap-min", &min)) {
			j++;
			has_min = true;
		}

		if (!of_property_read_u32(node, "powercap-max", &max)) {
			j++;
			has_max = true;
		}

		if (!of_property_read_u32(node, "powercap-current", &cur)) {
			j++;
			has_cur = true;
		}

		pcaps[i].pattrs = kcalloc(j, sizeof(struct powercap_attr),
					  GFP_KERNEL);
		if (!pcaps[i].pattrs)
			goto out_pcaps_pattrs;

		pcaps[i].pg.attrs = kcalloc(j + 1, sizeof(struct attribute *),
					    GFP_KERNEL);
		if (!pcaps[i].pg.attrs) {
			kfree(pcaps[i].pattrs);
			goto out_pcaps_pattrs;
		}

		j = 0;
		pcaps[i].pg.name = kasprintf(GFP_KERNEL, "%pOFn", node);
		if (has_min) {
			powercap_add_attr(min, "powercap-min",
					  &pcaps[i].pattrs[j]);
			pcaps[i].pg.attrs[j] = &pcaps[i].pattrs[j].attr.attr;
			j++;
		}

		if (has_max) {
			powercap_add_attr(max, "powercap-max",
					  &pcaps[i].pattrs[j]);
			pcaps[i].pg.attrs[j] = &pcaps[i].pattrs[j].attr.attr;
			j++;
		}

		if (has_cur) {
			powercap_add_attr(cur, "powercap-current",
					  &pcaps[i].pattrs[j]);
			pcaps[i].pattrs[j].attr.attr.mode |= 0220;
			pcaps[i].pattrs[j].attr.store = powercap_store;
			pcaps[i].pg.attrs[j] = &pcaps[i].pattrs[j].attr.attr;
			j++;
		}

		if (sysfs_create_group(powercap_kobj, &pcaps[i].pg)) {
			pr_warn("Failed to create powercap attribute group %s\n",
				pcaps[i].pg.name);
			goto out_pcaps_pattrs;
		}
		i++;
	}

	return;

out_pcaps_pattrs:
	while (--i >= 0) {
		kfree(pcaps[i].pattrs);
		kfree(pcaps[i].pg.attrs);
		kfree(pcaps[i].pg.name);
	}
	kobject_put(powercap_kobj);
out_pcaps:
	kfree(pcaps);
}
