// SPDX-License-Identifier: GPL-2.0
/*
 * System Control and Management Interface (SCMI) Powercap Protocol
 *
 * Copyright (C) 2022 ARM Ltd.
 */

#define pr_fmt(fmt) "SCMI Notifications POWERCAP - " fmt

#include <linux/bitfield.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/scmi_protocol.h>

#include <trace/events/scmi.h>

#include "protocols.h"
#include "notify.h"

/* Updated only after ALL the mandatory features for that version are merged */
#define SCMI_PROTOCOL_SUPPORTED_VERSION		0x20000

enum scmi_powercap_protocol_cmd {
	POWERCAP_DOMAIN_ATTRIBUTES = 0x3,
	POWERCAP_CAP_GET = 0x4,
	POWERCAP_CAP_SET = 0x5,
	POWERCAP_PAI_GET = 0x6,
	POWERCAP_PAI_SET = 0x7,
	POWERCAP_DOMAIN_NAME_GET = 0x8,
	POWERCAP_MEASUREMENTS_GET = 0x9,
	POWERCAP_CAP_NOTIFY = 0xa,
	POWERCAP_MEASUREMENTS_NOTIFY = 0xb,
	POWERCAP_DESCRIBE_FASTCHANNEL = 0xc,
};

enum {
	POWERCAP_FC_CAP,
	POWERCAP_FC_PAI,
	POWERCAP_FC_MAX,
};

struct scmi_msg_resp_powercap_domain_attributes {
	__le32 attributes;
#define SUPPORTS_POWERCAP_CAP_CHANGE_NOTIFY(x)		((x) & BIT(31))
#define SUPPORTS_POWERCAP_MEASUREMENTS_CHANGE_NOTIFY(x)	((x) & BIT(30))
#define SUPPORTS_ASYNC_POWERCAP_CAP_SET(x)		((x) & BIT(29))
#define SUPPORTS_EXTENDED_NAMES(x)			((x) & BIT(28))
#define SUPPORTS_POWERCAP_CAP_CONFIGURATION(x)		((x) & BIT(27))
#define SUPPORTS_POWERCAP_MONITORING(x)			((x) & BIT(26))
#define SUPPORTS_POWERCAP_PAI_CONFIGURATION(x)		((x) & BIT(25))
#define SUPPORTS_POWERCAP_FASTCHANNELS(x)		((x) & BIT(22))
#define POWERCAP_POWER_UNIT(x)				\
		(FIELD_GET(GENMASK(24, 23), (x)))
#define	SUPPORTS_POWER_UNITS_MW(x)			\
		(POWERCAP_POWER_UNIT(x) == 0x2)
#define	SUPPORTS_POWER_UNITS_UW(x)			\
		(POWERCAP_POWER_UNIT(x) == 0x1)
	u8 name[SCMI_SHORT_NAME_MAX_SIZE];
	__le32 min_pai;
	__le32 max_pai;
	__le32 pai_step;
	__le32 min_power_cap;
	__le32 max_power_cap;
	__le32 power_cap_step;
	__le32 sustainable_power;
	__le32 accuracy;
	__le32 parent_id;
};

struct scmi_msg_powercap_set_cap_or_pai {
	__le32 domain;
	__le32 flags;
#define CAP_SET_ASYNC		BIT(1)
#define CAP_SET_IGNORE_DRESP	BIT(0)
	__le32 value;
};

struct scmi_msg_resp_powercap_cap_set_complete {
	__le32 domain;
	__le32 power_cap;
};

struct scmi_msg_resp_powercap_meas_get {
	__le32 power;
	__le32 pai;
};

struct scmi_msg_powercap_notify_cap {
	__le32 domain;
	__le32 notify_enable;
};

struct scmi_msg_powercap_notify_thresh {
	__le32 domain;
	__le32 notify_enable;
	__le32 power_thresh_low;
	__le32 power_thresh_high;
};

struct scmi_powercap_cap_changed_notify_payld {
	__le32 agent_id;
	__le32 domain_id;
	__le32 power_cap;
	__le32 pai;
};

struct scmi_powercap_meas_changed_notify_payld {
	__le32 agent_id;
	__le32 domain_id;
	__le32 power;
};

struct scmi_powercap_state {
	bool enabled;
	u32 last_pcap;
	bool meas_notif_enabled;
	u64 thresholds;
#define THRESH_LOW(p, id)				\
	(lower_32_bits((p)->states[(id)].thresholds))
#define THRESH_HIGH(p, id)				\
	(upper_32_bits((p)->states[(id)].thresholds))
};

struct powercap_info {
	u32 version;
	int num_domains;
	bool notify_cap_cmd;
	bool notify_measurements_cmd;
	struct scmi_powercap_state *states;
	struct scmi_powercap_info *powercaps;
};

static enum scmi_powercap_protocol_cmd evt_2_cmd[] = {
	POWERCAP_CAP_NOTIFY,
	POWERCAP_MEASUREMENTS_NOTIFY,
};

static int scmi_powercap_notify(const struct scmi_protocol_handle *ph,
				u32 domain, int message_id, bool enable);

static int
scmi_powercap_attributes_get(const struct scmi_protocol_handle *ph,
			     struct powercap_info *pi)
{
	int ret;
	struct scmi_xfer *t;

	ret = ph->xops->xfer_get_init(ph, PROTOCOL_ATTRIBUTES, 0,
				      sizeof(u32), &t);
	if (ret)
		return ret;

	ret = ph->xops->do_xfer(ph, t);
	if (!ret) {
		u32 attributes;

		attributes = get_unaligned_le32(t->rx.buf);
		pi->num_domains = FIELD_GET(GENMASK(15, 0), attributes);
	}

	ph->xops->xfer_put(ph, t);

	if (!ret) {
		if (!ph->hops->protocol_msg_check(ph,
						  POWERCAP_CAP_NOTIFY, NULL))
			pi->notify_cap_cmd = true;

		if (!ph->hops->protocol_msg_check(ph,
						  POWERCAP_MEASUREMENTS_NOTIFY,
						  NULL))
			pi->notify_measurements_cmd = true;
	}

	return ret;
}

static inline int
scmi_powercap_validate(unsigned int min_val, unsigned int max_val,
		       unsigned int step_val, bool configurable)
{
	if (!min_val || !max_val)
		return -EPROTO;

	if ((configurable && min_val == max_val) ||
	    (!configurable && min_val != max_val))
		return -EPROTO;

	if (min_val != max_val && !step_val)
		return -EPROTO;

	return 0;
}

static int
scmi_powercap_domain_attributes_get(const struct scmi_protocol_handle *ph,
				    struct powercap_info *pinfo, u32 domain)
{
	int ret;
	u32 flags;
	struct scmi_xfer *t;
	struct scmi_powercap_info *dom_info = pinfo->powercaps + domain;
	struct scmi_msg_resp_powercap_domain_attributes *resp;

	ret = ph->xops->xfer_get_init(ph, POWERCAP_DOMAIN_ATTRIBUTES,
				      sizeof(domain), sizeof(*resp), &t);
	if (ret)
		return ret;

	put_unaligned_le32(domain, t->tx.buf);
	resp = t->rx.buf;

	ret = ph->xops->do_xfer(ph, t);
	if (!ret) {
		flags = le32_to_cpu(resp->attributes);

		dom_info->id = domain;
		if (pinfo->notify_cap_cmd)
			dom_info->notify_powercap_cap_change =
				SUPPORTS_POWERCAP_CAP_CHANGE_NOTIFY(flags);
		if (pinfo->notify_measurements_cmd)
			dom_info->notify_powercap_measurement_change =
				SUPPORTS_POWERCAP_MEASUREMENTS_CHANGE_NOTIFY(flags);
		dom_info->async_powercap_cap_set =
			SUPPORTS_ASYNC_POWERCAP_CAP_SET(flags);
		dom_info->powercap_cap_config =
			SUPPORTS_POWERCAP_CAP_CONFIGURATION(flags);
		dom_info->powercap_monitoring =
			SUPPORTS_POWERCAP_MONITORING(flags);
		dom_info->powercap_pai_config =
			SUPPORTS_POWERCAP_PAI_CONFIGURATION(flags);
		dom_info->powercap_scale_mw =
			SUPPORTS_POWER_UNITS_MW(flags);
		dom_info->powercap_scale_uw =
			SUPPORTS_POWER_UNITS_UW(flags);
		dom_info->fastchannels =
			SUPPORTS_POWERCAP_FASTCHANNELS(flags);

		strscpy(dom_info->name, resp->name, SCMI_SHORT_NAME_MAX_SIZE);

		dom_info->min_pai = le32_to_cpu(resp->min_pai);
		dom_info->max_pai = le32_to_cpu(resp->max_pai);
		dom_info->pai_step = le32_to_cpu(resp->pai_step);
		ret = scmi_powercap_validate(dom_info->min_pai,
					     dom_info->max_pai,
					     dom_info->pai_step,
					     dom_info->powercap_pai_config);
		if (ret) {
			dev_err(ph->dev,
				"Platform reported inconsistent PAI config for domain %d - %s\n",
				dom_info->id, dom_info->name);
			goto clean;
		}

		dom_info->min_power_cap = le32_to_cpu(resp->min_power_cap);
		dom_info->max_power_cap = le32_to_cpu(resp->max_power_cap);
		dom_info->power_cap_step = le32_to_cpu(resp->power_cap_step);
		ret = scmi_powercap_validate(dom_info->min_power_cap,
					     dom_info->max_power_cap,
					     dom_info->power_cap_step,
					     dom_info->powercap_cap_config);
		if (ret) {
			dev_err(ph->dev,
				"Platform reported inconsistent CAP config for domain %d - %s\n",
				dom_info->id, dom_info->name);
			goto clean;
		}

		dom_info->sustainable_power =
			le32_to_cpu(resp->sustainable_power);
		dom_info->accuracy = le32_to_cpu(resp->accuracy);

		dom_info->parent_id = le32_to_cpu(resp->parent_id);
		if (dom_info->parent_id != SCMI_POWERCAP_ROOT_ZONE_ID &&
		    (dom_info->parent_id >= pinfo->num_domains ||
		     dom_info->parent_id == dom_info->id)) {
			dev_err(ph->dev,
				"Platform reported inconsistent parent ID for domain %d - %s\n",
				dom_info->id, dom_info->name);
			ret = -ENODEV;
		}
	}

clean:
	ph->xops->xfer_put(ph, t);

	/*
	 * If supported overwrite short name with the extended one;
	 * on error just carry on and use already provided short name.
	 */
	if (!ret && SUPPORTS_EXTENDED_NAMES(flags))
		ph->hops->extended_name_get(ph, POWERCAP_DOMAIN_NAME_GET,
					    domain, NULL, dom_info->name,
					    SCMI_MAX_STR_SIZE);

	return ret;
}

static int scmi_powercap_num_domains_get(const struct scmi_protocol_handle *ph)
{
	struct powercap_info *pi = ph->get_priv(ph);

	return pi->num_domains;
}

static const struct scmi_powercap_info *
scmi_powercap_dom_info_get(const struct scmi_protocol_handle *ph, u32 domain_id)
{
	struct powercap_info *pi = ph->get_priv(ph);

	if (domain_id >= pi->num_domains)
		return NULL;

	return pi->powercaps + domain_id;
}

static int scmi_powercap_xfer_cap_get(const struct scmi_protocol_handle *ph,
				      u32 domain_id, u32 *power_cap)
{
	int ret;
	struct scmi_xfer *t;

	ret = ph->xops->xfer_get_init(ph, POWERCAP_CAP_GET, sizeof(u32),
				      sizeof(u32), &t);
	if (ret)
		return ret;

	put_unaligned_le32(domain_id, t->tx.buf);
	ret = ph->xops->do_xfer(ph, t);
	if (!ret)
		*power_cap = get_unaligned_le32(t->rx.buf);

	ph->xops->xfer_put(ph, t);

	return ret;
}

static int __scmi_powercap_cap_get(const struct scmi_protocol_handle *ph,
				   const struct scmi_powercap_info *dom,
				   u32 *power_cap)
{
	if (dom->fc_info && dom->fc_info[POWERCAP_FC_CAP].get_addr) {
		*power_cap = ioread32(dom->fc_info[POWERCAP_FC_CAP].get_addr);
		trace_scmi_fc_call(SCMI_PROTOCOL_POWERCAP, POWERCAP_CAP_GET,
				   dom->id, *power_cap, 0);
		return 0;
	}

	return scmi_powercap_xfer_cap_get(ph, dom->id, power_cap);
}

static int scmi_powercap_cap_get(const struct scmi_protocol_handle *ph,
				 u32 domain_id, u32 *power_cap)
{
	const struct scmi_powercap_info *dom;

	if (!power_cap)
		return -EINVAL;

	dom = scmi_powercap_dom_info_get(ph, domain_id);
	if (!dom)
		return -EINVAL;

	return __scmi_powercap_cap_get(ph, dom, power_cap);
}

static int scmi_powercap_xfer_cap_set(const struct scmi_protocol_handle *ph,
				      const struct scmi_powercap_info *pc,
				      u32 power_cap, bool ignore_dresp)
{
	int ret;
	struct scmi_xfer *t;
	struct scmi_msg_powercap_set_cap_or_pai *msg;

	ret = ph->xops->xfer_get_init(ph, POWERCAP_CAP_SET,
				      sizeof(*msg), 0, &t);
	if (ret)
		return ret;

	msg = t->tx.buf;
	msg->domain = cpu_to_le32(pc->id);
	msg->flags =
		cpu_to_le32(FIELD_PREP(CAP_SET_ASYNC, pc->async_powercap_cap_set) |
			    FIELD_PREP(CAP_SET_IGNORE_DRESP, ignore_dresp));
	msg->value = cpu_to_le32(power_cap);

	if (!pc->async_powercap_cap_set || ignore_dresp) {
		ret = ph->xops->do_xfer(ph, t);
	} else {
		ret = ph->xops->do_xfer_with_response(ph, t);
		if (!ret) {
			struct scmi_msg_resp_powercap_cap_set_complete *resp;

			resp = t->rx.buf;
			if (le32_to_cpu(resp->domain) == pc->id)
				dev_dbg(ph->dev,
					"Powercap ID %d CAP set async to %u\n",
					pc->id,
					get_unaligned_le32(&resp->power_cap));
			else
				ret = -EPROTO;
		}
	}

	ph->xops->xfer_put(ph, t);
	return ret;
}

static int __scmi_powercap_cap_set(const struct scmi_protocol_handle *ph,
				   struct powercap_info *pi, u32 domain_id,
				   u32 power_cap, bool ignore_dresp)
{
	int ret = -EINVAL;
	const struct scmi_powercap_info *pc;

	pc = scmi_powercap_dom_info_get(ph, domain_id);
	if (!pc || !pc->powercap_cap_config)
		return ret;

	if (power_cap &&
	    (power_cap < pc->min_power_cap || power_cap > pc->max_power_cap))
		return ret;

	if (pc->fc_info && pc->fc_info[POWERCAP_FC_CAP].set_addr) {
		struct scmi_fc_info *fci = &pc->fc_info[POWERCAP_FC_CAP];

		iowrite32(power_cap, fci->set_addr);
		ph->hops->fastchannel_db_ring(fci->set_db);
		trace_scmi_fc_call(SCMI_PROTOCOL_POWERCAP, POWERCAP_CAP_SET,
				   domain_id, power_cap, 0);
		ret = 0;
	} else {
		ret = scmi_powercap_xfer_cap_set(ph, pc, power_cap,
						 ignore_dresp);
	}

	/* Save the last explicitly set non-zero powercap value */
	if (PROTOCOL_REV_MAJOR(pi->version) >= 0x2 && !ret && power_cap)
		pi->states[domain_id].last_pcap = power_cap;

	return ret;
}

static int scmi_powercap_cap_set(const struct scmi_protocol_handle *ph,
				 u32 domain_id, u32 power_cap,
				 bool ignore_dresp)
{
	struct powercap_info *pi = ph->get_priv(ph);

	/*
	 * Disallow zero as a possible explicitly requested powercap:
	 * there are enable/disable operations for this.
	 */
	if (!power_cap)
		return -EINVAL;

	/* Just log the last set request if acting on a disabled domain */
	if (PROTOCOL_REV_MAJOR(pi->version) >= 0x2 &&
	    !pi->states[domain_id].enabled) {
		pi->states[domain_id].last_pcap = power_cap;
		return 0;
	}

	return __scmi_powercap_cap_set(ph, pi, domain_id,
				       power_cap, ignore_dresp);
}

static int scmi_powercap_xfer_pai_get(const struct scmi_protocol_handle *ph,
				      u32 domain_id, u32 *pai)
{
	int ret;
	struct scmi_xfer *t;

	ret = ph->xops->xfer_get_init(ph, POWERCAP_PAI_GET, sizeof(u32),
				      sizeof(u32), &t);
	if (ret)
		return ret;

	put_unaligned_le32(domain_id, t->tx.buf);
	ret = ph->xops->do_xfer(ph, t);
	if (!ret)
		*pai = get_unaligned_le32(t->rx.buf);

	ph->xops->xfer_put(ph, t);

	return ret;
}

static int scmi_powercap_pai_get(const struct scmi_protocol_handle *ph,
				 u32 domain_id, u32 *pai)
{
	struct scmi_powercap_info *dom;
	struct powercap_info *pi = ph->get_priv(ph);

	if (!pai || domain_id >= pi->num_domains)
		return -EINVAL;

	dom = pi->powercaps + domain_id;
	if (dom->fc_info && dom->fc_info[POWERCAP_FC_PAI].get_addr) {
		*pai = ioread32(dom->fc_info[POWERCAP_FC_PAI].get_addr);
		trace_scmi_fc_call(SCMI_PROTOCOL_POWERCAP, POWERCAP_PAI_GET,
				   domain_id, *pai, 0);
		return 0;
	}

	return scmi_powercap_xfer_pai_get(ph, domain_id, pai);
}

static int scmi_powercap_xfer_pai_set(const struct scmi_protocol_handle *ph,
				      u32 domain_id, u32 pai)
{
	int ret;
	struct scmi_xfer *t;
	struct scmi_msg_powercap_set_cap_or_pai *msg;

	ret = ph->xops->xfer_get_init(ph, POWERCAP_PAI_SET,
				      sizeof(*msg), 0, &t);
	if (ret)
		return ret;

	msg = t->tx.buf;
	msg->domain = cpu_to_le32(domain_id);
	msg->flags = cpu_to_le32(0);
	msg->value = cpu_to_le32(pai);

	ret = ph->xops->do_xfer(ph, t);

	ph->xops->xfer_put(ph, t);
	return ret;
}

static int scmi_powercap_pai_set(const struct scmi_protocol_handle *ph,
				 u32 domain_id, u32 pai)
{
	const struct scmi_powercap_info *pc;

	pc = scmi_powercap_dom_info_get(ph, domain_id);
	if (!pc || !pc->powercap_pai_config || !pai ||
	    pai < pc->min_pai || pai > pc->max_pai)
		return -EINVAL;

	if (pc->fc_info && pc->fc_info[POWERCAP_FC_PAI].set_addr) {
		struct scmi_fc_info *fci = &pc->fc_info[POWERCAP_FC_PAI];

		trace_scmi_fc_call(SCMI_PROTOCOL_POWERCAP, POWERCAP_PAI_SET,
				   domain_id, pai, 0);
		iowrite32(pai, fci->set_addr);
		ph->hops->fastchannel_db_ring(fci->set_db);
		return 0;
	}

	return scmi_powercap_xfer_pai_set(ph, domain_id, pai);
}

static int scmi_powercap_measurements_get(const struct scmi_protocol_handle *ph,
					  u32 domain_id, u32 *average_power,
					  u32 *pai)
{
	int ret;
	struct scmi_xfer *t;
	struct scmi_msg_resp_powercap_meas_get *resp;
	const struct scmi_powercap_info *pc;

	pc = scmi_powercap_dom_info_get(ph, domain_id);
	if (!pc || !pc->powercap_monitoring || !pai || !average_power)
		return -EINVAL;

	ret = ph->xops->xfer_get_init(ph, POWERCAP_MEASUREMENTS_GET,
				      sizeof(u32), sizeof(*resp), &t);
	if (ret)
		return ret;

	resp = t->rx.buf;
	put_unaligned_le32(domain_id, t->tx.buf);
	ret = ph->xops->do_xfer(ph, t);
	if (!ret) {
		*average_power = le32_to_cpu(resp->power);
		*pai = le32_to_cpu(resp->pai);
	}

	ph->xops->xfer_put(ph, t);
	return ret;
}

static int
scmi_powercap_measurements_threshold_get(const struct scmi_protocol_handle *ph,
					 u32 domain_id, u32 *power_thresh_low,
					 u32 *power_thresh_high)
{
	struct powercap_info *pi = ph->get_priv(ph);

	if (!power_thresh_low || !power_thresh_high ||
	    domain_id >= pi->num_domains)
		return -EINVAL;

	*power_thresh_low =  THRESH_LOW(pi, domain_id);
	*power_thresh_high = THRESH_HIGH(pi, domain_id);

	return 0;
}

static int
scmi_powercap_measurements_threshold_set(const struct scmi_protocol_handle *ph,
					 u32 domain_id, u32 power_thresh_low,
					 u32 power_thresh_high)
{
	int ret = 0;
	struct powercap_info *pi = ph->get_priv(ph);

	if (domain_id >= pi->num_domains ||
	    power_thresh_low > power_thresh_high)
		return -EINVAL;

	/* Anything to do ? */
	if (THRESH_LOW(pi, domain_id) == power_thresh_low &&
	    THRESH_HIGH(pi, domain_id) == power_thresh_high)
		return ret;

	pi->states[domain_id].thresholds =
		(FIELD_PREP(GENMASK_ULL(31, 0), power_thresh_low) |
		 FIELD_PREP(GENMASK_ULL(63, 32), power_thresh_high));

	/* Update thresholds if notification already enabled */
	if (pi->states[domain_id].meas_notif_enabled)
		ret = scmi_powercap_notify(ph, domain_id,
					   POWERCAP_MEASUREMENTS_NOTIFY,
					   true);

	return ret;
}

static int scmi_powercap_cap_enable_set(const struct scmi_protocol_handle *ph,
					u32 domain_id, bool enable)
{
	int ret;
	u32 power_cap;
	struct powercap_info *pi = ph->get_priv(ph);

	if (PROTOCOL_REV_MAJOR(pi->version) < 0x2)
		return -EINVAL;

	if (enable == pi->states[domain_id].enabled)
		return 0;

	if (enable) {
		/* Cannot enable with a zero powercap. */
		if (!pi->states[domain_id].last_pcap)
			return -EINVAL;

		ret = __scmi_powercap_cap_set(ph, pi, domain_id,
					      pi->states[domain_id].last_pcap,
					      true);
	} else {
		ret = __scmi_powercap_cap_set(ph, pi, domain_id, 0, true);
	}

	if (ret)
		return ret;

	/*
	 * Update our internal state to reflect final platform state: the SCMI
	 * server could have ignored a disable request and kept enforcing some
	 * powercap limit requested by other agents.
	 */
	ret = scmi_powercap_cap_get(ph, domain_id, &power_cap);
	if (!ret)
		pi->states[domain_id].enabled = !!power_cap;

	return ret;
}

static int scmi_powercap_cap_enable_get(const struct scmi_protocol_handle *ph,
					u32 domain_id, bool *enable)
{
	int ret;
	u32 power_cap;
	struct powercap_info *pi = ph->get_priv(ph);

	*enable = true;
	if (PROTOCOL_REV_MAJOR(pi->version) < 0x2)
		return 0;

	/*
	 * Report always real platform state; platform could have ignored
	 * a previous disable request. Default true on any error.
	 */
	ret = scmi_powercap_cap_get(ph, domain_id, &power_cap);
	if (!ret)
		*enable = !!power_cap;

	/* Update internal state with current real platform state */
	pi->states[domain_id].enabled = *enable;

	return 0;
}

static const struct scmi_powercap_proto_ops powercap_proto_ops = {
	.num_domains_get = scmi_powercap_num_domains_get,
	.info_get = scmi_powercap_dom_info_get,
	.cap_get = scmi_powercap_cap_get,
	.cap_set = scmi_powercap_cap_set,
	.cap_enable_set = scmi_powercap_cap_enable_set,
	.cap_enable_get = scmi_powercap_cap_enable_get,
	.pai_get = scmi_powercap_pai_get,
	.pai_set = scmi_powercap_pai_set,
	.measurements_get = scmi_powercap_measurements_get,
	.measurements_threshold_set = scmi_powercap_measurements_threshold_set,
	.measurements_threshold_get = scmi_powercap_measurements_threshold_get,
};

static void scmi_powercap_domain_init_fc(const struct scmi_protocol_handle *ph,
					 u32 domain, struct scmi_fc_info **p_fc)
{
	struct scmi_fc_info *fc;

	fc = devm_kcalloc(ph->dev, POWERCAP_FC_MAX, sizeof(*fc), GFP_KERNEL);
	if (!fc)
		return;

	ph->hops->fastchannel_init(ph, POWERCAP_DESCRIBE_FASTCHANNEL,
				   POWERCAP_CAP_SET, 4, domain,
				   &fc[POWERCAP_FC_CAP].set_addr,
				   &fc[POWERCAP_FC_CAP].set_db,
				   &fc[POWERCAP_FC_CAP].rate_limit);

	ph->hops->fastchannel_init(ph, POWERCAP_DESCRIBE_FASTCHANNEL,
				   POWERCAP_CAP_GET, 4, domain,
				   &fc[POWERCAP_FC_CAP].get_addr, NULL,
				   &fc[POWERCAP_FC_CAP].rate_limit);

	ph->hops->fastchannel_init(ph, POWERCAP_DESCRIBE_FASTCHANNEL,
				   POWERCAP_PAI_SET, 4, domain,
				   &fc[POWERCAP_FC_PAI].set_addr,
				   &fc[POWERCAP_FC_PAI].set_db,
				   &fc[POWERCAP_FC_PAI].rate_limit);

	ph->hops->fastchannel_init(ph, POWERCAP_DESCRIBE_FASTCHANNEL,
				   POWERCAP_PAI_GET, 4, domain,
				   &fc[POWERCAP_FC_PAI].get_addr, NULL,
				   &fc[POWERCAP_PAI_GET].rate_limit);

	*p_fc = fc;
}

static int scmi_powercap_notify(const struct scmi_protocol_handle *ph,
				u32 domain, int message_id, bool enable)
{
	int ret;
	struct scmi_xfer *t;

	switch (message_id) {
	case POWERCAP_CAP_NOTIFY:
	{
		struct scmi_msg_powercap_notify_cap *notify;

		ret = ph->xops->xfer_get_init(ph, message_id,
					      sizeof(*notify), 0, &t);
		if (ret)
			return ret;

		notify = t->tx.buf;
		notify->domain = cpu_to_le32(domain);
		notify->notify_enable = cpu_to_le32(enable ? BIT(0) : 0);
		break;
	}
	case POWERCAP_MEASUREMENTS_NOTIFY:
	{
		u32 low, high;
		struct scmi_msg_powercap_notify_thresh *notify;

		/*
		 * Note that we have to pick the most recently configured
		 * thresholds to build a proper POWERCAP_MEASUREMENTS_NOTIFY
		 * enable request and we fail, complaining, if no thresholds
		 * were ever set, since this is an indication the API has been
		 * used wrongly.
		 */
		ret = scmi_powercap_measurements_threshold_get(ph, domain,
							       &low, &high);
		if (ret)
			return ret;

		if (enable && !low && !high) {
			dev_err(ph->dev,
				"Invalid Measurements Notify thresholds: %u/%u\n",
				low, high);
			return -EINVAL;
		}

		ret = ph->xops->xfer_get_init(ph, message_id,
					      sizeof(*notify), 0, &t);
		if (ret)
			return ret;

		notify = t->tx.buf;
		notify->domain = cpu_to_le32(domain);
		notify->notify_enable = cpu_to_le32(enable ? BIT(0) : 0);
		notify->power_thresh_low = cpu_to_le32(low);
		notify->power_thresh_high = cpu_to_le32(high);
		break;
	}
	default:
		return -EINVAL;
	}

	ret = ph->xops->do_xfer(ph, t);

	ph->xops->xfer_put(ph, t);
	return ret;
}

static bool
scmi_powercap_notify_supported(const struct scmi_protocol_handle *ph,
			       u8 evt_id, u32 src_id)
{
	bool supported = false;
	const struct scmi_powercap_info *dom_info;
	struct powercap_info *pi = ph->get_priv(ph);

	if (evt_id >= ARRAY_SIZE(evt_2_cmd) || src_id >= pi->num_domains)
		return false;

	dom_info = pi->powercaps + src_id;
	if (evt_id == SCMI_EVENT_POWERCAP_CAP_CHANGED)
		supported = dom_info->notify_powercap_cap_change;
	else if (evt_id == SCMI_EVENT_POWERCAP_MEASUREMENTS_CHANGED)
		supported = dom_info->notify_powercap_measurement_change;

	return supported;
}

static int
scmi_powercap_set_notify_enabled(const struct scmi_protocol_handle *ph,
				 u8 evt_id, u32 src_id, bool enable)
{
	int ret, cmd_id;
	struct powercap_info *pi = ph->get_priv(ph);

	if (evt_id >= ARRAY_SIZE(evt_2_cmd) || src_id >= pi->num_domains)
		return -EINVAL;

	cmd_id = evt_2_cmd[evt_id];
	ret = scmi_powercap_notify(ph, src_id, cmd_id, enable);
	if (ret)
		pr_debug("FAIL_ENABLED - evt[%X] dom[%d] - ret:%d\n",
			 evt_id, src_id, ret);
	else if (cmd_id == POWERCAP_MEASUREMENTS_NOTIFY)
		/*
		 * On success save the current notification enabled state, so
		 * as to be able to properly update the notification thresholds
		 * when they are modified on a domain for which measurement
		 * notifications were currently enabled.
		 *
		 * This is needed because the SCMI Notification core machinery
		 * and API does not support passing per-notification custom
		 * arguments at callback registration time.
		 *
		 * Note that this can be done here with a simple flag since the
		 * SCMI core Notifications code takes care of keeping proper
		 * per-domain enables refcounting, so that this helper function
		 * will be called only once (for enables) when the first user
		 * registers a callback on this domain and once more (disable)
		 * when the last user de-registers its callback.
		 */
		pi->states[src_id].meas_notif_enabled = enable;

	return ret;
}

static void *
scmi_powercap_fill_custom_report(const struct scmi_protocol_handle *ph,
				 u8 evt_id, ktime_t timestamp,
				 const void *payld, size_t payld_sz,
				 void *report, u32 *src_id)
{
	void *rep = NULL;

	switch (evt_id) {
	case SCMI_EVENT_POWERCAP_CAP_CHANGED:
	{
		const struct scmi_powercap_cap_changed_notify_payld *p = payld;
		struct scmi_powercap_cap_changed_report *r = report;

		if (sizeof(*p) != payld_sz)
			break;

		r->timestamp = timestamp;
		r->agent_id = le32_to_cpu(p->agent_id);
		r->domain_id = le32_to_cpu(p->domain_id);
		r->power_cap = le32_to_cpu(p->power_cap);
		r->pai = le32_to_cpu(p->pai);
		*src_id = r->domain_id;
		rep = r;
		break;
	}
	case SCMI_EVENT_POWERCAP_MEASUREMENTS_CHANGED:
	{
		const struct scmi_powercap_meas_changed_notify_payld *p = payld;
		struct scmi_powercap_meas_changed_report *r = report;

		if (sizeof(*p) != payld_sz)
			break;

		r->timestamp = timestamp;
		r->agent_id = le32_to_cpu(p->agent_id);
		r->domain_id = le32_to_cpu(p->domain_id);
		r->power = le32_to_cpu(p->power);
		*src_id = r->domain_id;
		rep = r;
		break;
	}
	default:
		break;
	}

	return rep;
}

static int
scmi_powercap_get_num_sources(const struct scmi_protocol_handle *ph)
{
	struct powercap_info *pi = ph->get_priv(ph);

	if (!pi)
		return -EINVAL;

	return pi->num_domains;
}

static const struct scmi_event powercap_events[] = {
	{
		.id = SCMI_EVENT_POWERCAP_CAP_CHANGED,
		.max_payld_sz =
			sizeof(struct scmi_powercap_cap_changed_notify_payld),
		.max_report_sz =
			sizeof(struct scmi_powercap_cap_changed_report),
	},
	{
		.id = SCMI_EVENT_POWERCAP_MEASUREMENTS_CHANGED,
		.max_payld_sz =
			sizeof(struct scmi_powercap_meas_changed_notify_payld),
		.max_report_sz =
			sizeof(struct scmi_powercap_meas_changed_report),
	},
};

static const struct scmi_event_ops powercap_event_ops = {
	.is_notify_supported = scmi_powercap_notify_supported,
	.get_num_sources = scmi_powercap_get_num_sources,
	.set_notify_enabled = scmi_powercap_set_notify_enabled,
	.fill_custom_report = scmi_powercap_fill_custom_report,
};

static const struct scmi_protocol_events powercap_protocol_events = {
	.queue_sz = SCMI_PROTO_QUEUE_SZ,
	.ops = &powercap_event_ops,
	.evts = powercap_events,
	.num_events = ARRAY_SIZE(powercap_events),
};

static int
scmi_powercap_protocol_init(const struct scmi_protocol_handle *ph)
{
	int domain, ret;
	u32 version;
	struct powercap_info *pinfo;

	ret = ph->xops->version_get(ph, &version);
	if (ret)
		return ret;

	dev_dbg(ph->dev, "Powercap Version %d.%d\n",
		PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version));

	pinfo = devm_kzalloc(ph->dev, sizeof(*pinfo), GFP_KERNEL);
	if (!pinfo)
		return -ENOMEM;

	ret = scmi_powercap_attributes_get(ph, pinfo);
	if (ret)
		return ret;

	pinfo->powercaps = devm_kcalloc(ph->dev, pinfo->num_domains,
					sizeof(*pinfo->powercaps),
					GFP_KERNEL);
	if (!pinfo->powercaps)
		return -ENOMEM;

	pinfo->states = devm_kcalloc(ph->dev, pinfo->num_domains,
				     sizeof(*pinfo->states), GFP_KERNEL);
	if (!pinfo->states)
		return -ENOMEM;

	/*
	 * Note that any failure in retrieving any domain attribute leads to
	 * the whole Powercap protocol initialization failure: this way the
	 * reported Powercap domains are all assured, when accessed, to be well
	 * formed and correlated by sane parent-child relationship (if any).
	 */
	for (domain = 0; domain < pinfo->num_domains; domain++) {
		ret = scmi_powercap_domain_attributes_get(ph, pinfo, domain);
		if (ret)
			return ret;

		if (pinfo->powercaps[domain].fastchannels)
			scmi_powercap_domain_init_fc(ph, domain,
						     &pinfo->powercaps[domain].fc_info);

		/* Grab initial state when disable is supported. */
		if (PROTOCOL_REV_MAJOR(version) >= 0x2) {
			ret = __scmi_powercap_cap_get(ph,
						      &pinfo->powercaps[domain],
						      &pinfo->states[domain].last_pcap);
			if (ret)
				return ret;

			pinfo->states[domain].enabled =
				!!pinfo->states[domain].last_pcap;
		}
	}

	pinfo->version = version;
	return ph->set_priv(ph, pinfo, version);
}

static const struct scmi_protocol scmi_powercap = {
	.id = SCMI_PROTOCOL_POWERCAP,
	.owner = THIS_MODULE,
	.instance_init = &scmi_powercap_protocol_init,
	.ops = &powercap_proto_ops,
	.events = &powercap_protocol_events,
	.supported_version = SCMI_PROTOCOL_SUPPORTED_VERSION,
};

DEFINE_SCMI_PROTOCOL_REGISTER_UNREGISTER(powercap, scmi_powercap)
