// 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"

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 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;
	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);
	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;
		dom_info->notify_powercap_cap_change =
			SUPPORTS_POWERCAP_CAP_CHANGE_NOTIFY(flags);
		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, 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,
				 u32 domain_id, u32 *power_cap)
{
	struct scmi_powercap_info *dom;
	struct powercap_info *pi = ph->get_priv(ph);

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

	dom = pi->powercaps + domain_id;
	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,
				   domain_id, *power_cap, 0);
		return 0;
	}

	return scmi_powercap_xfer_cap_get(ph, domain_id, 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,
				 u32 domain_id, u32 power_cap,
				 bool ignore_dresp)
{
	const struct scmi_powercap_info *pc;

	pc = scmi_powercap_dom_info_get(ph, domain_id);
	if (!pc || !pc->powercap_cap_config || !power_cap ||
	    power_cap < pc->min_power_cap ||
	    power_cap > pc->max_power_cap)
		return -EINVAL;

	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);
		return 0;
	}

	return scmi_powercap_xfer_cap_set(ph, pc, 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 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,
	.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);

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

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

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

	*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 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 = {
	.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;

	/*
	 * 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);
	}

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

	pinfo->version = version;

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

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,
};

DEFINE_SCMI_PROTOCOL_REGISTER_UNREGISTER(powercap, scmi_powercap)
