// SPDX-License-Identifier: GPL-2.0
/*
 * Generic netlink for DPLL management framework
 *
 *  Copyright (c) 2023 Meta Platforms, Inc. and affiliates
 *  Copyright (c) 2023 Intel and affiliates
 *
 */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <net/genetlink.h>
#include "dpll_core.h"
#include "dpll_netlink.h"
#include "dpll_nl.h"
#include <uapi/linux/dpll.h>

#define ASSERT_NOT_NULL(ptr)	(WARN_ON(!ptr))

#define xa_for_each_marked_start(xa, index, entry, filter, start) \
	for (index = start, entry = xa_find(xa, &index, ULONG_MAX, filter); \
	     entry; entry = xa_find_after(xa, &index, ULONG_MAX, filter))

struct dpll_dump_ctx {
	unsigned long idx;
};

static struct dpll_dump_ctx *dpll_dump_context(struct netlink_callback *cb)
{
	return (struct dpll_dump_ctx *)cb->ctx;
}

static int
dpll_msg_add_dev_handle(struct sk_buff *msg, struct dpll_device *dpll)
{
	if (nla_put_u32(msg, DPLL_A_ID, dpll->id))
		return -EMSGSIZE;

	return 0;
}

static int
dpll_msg_add_dev_parent_handle(struct sk_buff *msg, u32 id)
{
	if (nla_put_u32(msg, DPLL_A_PIN_PARENT_ID, id))
		return -EMSGSIZE;

	return 0;
}

static bool dpll_pin_available(struct dpll_pin *pin)
{
	struct dpll_pin_ref *par_ref;
	unsigned long i;

	if (!xa_get_mark(&dpll_pin_xa, pin->id, DPLL_REGISTERED))
		return false;
	xa_for_each(&pin->parent_refs, i, par_ref)
		if (xa_get_mark(&dpll_pin_xa, par_ref->pin->id,
				DPLL_REGISTERED))
			return true;
	xa_for_each(&pin->dpll_refs, i, par_ref)
		if (xa_get_mark(&dpll_device_xa, par_ref->dpll->id,
				DPLL_REGISTERED))
			return true;
	return false;
}

/**
 * dpll_msg_add_pin_handle - attach pin handle attribute to a given message
 * @msg: pointer to sk_buff message to attach a pin handle
 * @pin: pin pointer
 *
 * Return:
 * * 0 - success
 * * -EMSGSIZE - no space in message to attach pin handle
 */
static int dpll_msg_add_pin_handle(struct sk_buff *msg, struct dpll_pin *pin)
{
	if (!pin)
		return 0;
	if (nla_put_u32(msg, DPLL_A_PIN_ID, pin->id))
		return -EMSGSIZE;
	return 0;
}

static struct dpll_pin *dpll_netdev_pin(const struct net_device *dev)
{
	return rcu_dereference_rtnl(dev->dpll_pin);
}

/**
 * dpll_netdev_pin_handle_size - get size of pin handle attribute of a netdev
 * @dev: netdev from which to get the pin
 *
 * Return: byte size of pin handle attribute, or 0 if @dev has no pin.
 */
size_t dpll_netdev_pin_handle_size(const struct net_device *dev)
{
	return dpll_netdev_pin(dev) ? nla_total_size(4) : 0; /* DPLL_A_PIN_ID */
}

int dpll_netdev_add_pin_handle(struct sk_buff *msg,
			       const struct net_device *dev)
{
	return dpll_msg_add_pin_handle(msg, dpll_netdev_pin(dev));
}

static int
dpll_msg_add_mode(struct sk_buff *msg, struct dpll_device *dpll,
		  struct netlink_ext_ack *extack)
{
	const struct dpll_device_ops *ops = dpll_device_ops(dpll);
	enum dpll_mode mode;
	int ret;

	ret = ops->mode_get(dpll, dpll_priv(dpll), &mode, extack);
	if (ret)
		return ret;
	if (nla_put_u32(msg, DPLL_A_MODE, mode))
		return -EMSGSIZE;

	return 0;
}

static int
dpll_msg_add_mode_supported(struct sk_buff *msg, struct dpll_device *dpll,
			    struct netlink_ext_ack *extack)
{
	const struct dpll_device_ops *ops = dpll_device_ops(dpll);
	enum dpll_mode mode;
	int ret;

	/* No mode change is supported now, so the only supported mode is the
	 * one obtained by mode_get().
	 */

	ret = ops->mode_get(dpll, dpll_priv(dpll), &mode, extack);
	if (ret)
		return ret;
	if (nla_put_u32(msg, DPLL_A_MODE_SUPPORTED, mode))
		return -EMSGSIZE;

	return 0;
}

static int
dpll_msg_add_phase_offset_monitor(struct sk_buff *msg, struct dpll_device *dpll,
				  struct netlink_ext_ack *extack)
{
	const struct dpll_device_ops *ops = dpll_device_ops(dpll);
	enum dpll_feature_state state;
	int ret;

	if (ops->phase_offset_monitor_set && ops->phase_offset_monitor_get) {
		ret = ops->phase_offset_monitor_get(dpll, dpll_priv(dpll),
						    &state, extack);
		if (ret)
			return ret;
		if (nla_put_u32(msg, DPLL_A_PHASE_OFFSET_MONITOR, state))
			return -EMSGSIZE;
	}

	return 0;
}

static int
dpll_msg_add_lock_status(struct sk_buff *msg, struct dpll_device *dpll,
			 struct netlink_ext_ack *extack)
{
	const struct dpll_device_ops *ops = dpll_device_ops(dpll);
	enum dpll_lock_status_error status_error = 0;
	enum dpll_lock_status status;
	int ret;

	ret = ops->lock_status_get(dpll, dpll_priv(dpll), &status,
				   &status_error, extack);
	if (ret)
		return ret;
	if (nla_put_u32(msg, DPLL_A_LOCK_STATUS, status))
		return -EMSGSIZE;
	if (status_error &&
	    (status == DPLL_LOCK_STATUS_UNLOCKED ||
	     status == DPLL_LOCK_STATUS_HOLDOVER) &&
	    nla_put_u32(msg, DPLL_A_LOCK_STATUS_ERROR, status_error))
		return -EMSGSIZE;

	return 0;
}

static int
dpll_msg_add_temp(struct sk_buff *msg, struct dpll_device *dpll,
		  struct netlink_ext_ack *extack)
{
	const struct dpll_device_ops *ops = dpll_device_ops(dpll);
	s32 temp;
	int ret;

	if (!ops->temp_get)
		return 0;
	ret = ops->temp_get(dpll, dpll_priv(dpll), &temp, extack);
	if (ret)
		return ret;
	if (nla_put_s32(msg, DPLL_A_TEMP, temp))
		return -EMSGSIZE;

	return 0;
}

static int
dpll_msg_add_clock_quality_level(struct sk_buff *msg, struct dpll_device *dpll,
				 struct netlink_ext_ack *extack)
{
	const struct dpll_device_ops *ops = dpll_device_ops(dpll);
	DECLARE_BITMAP(qls, DPLL_CLOCK_QUALITY_LEVEL_MAX) = { 0 };
	enum dpll_clock_quality_level ql;
	int ret;

	if (!ops->clock_quality_level_get)
		return 0;
	ret = ops->clock_quality_level_get(dpll, dpll_priv(dpll), qls, extack);
	if (ret)
		return ret;
	for_each_set_bit(ql, qls, DPLL_CLOCK_QUALITY_LEVEL_MAX)
		if (nla_put_u32(msg, DPLL_A_CLOCK_QUALITY_LEVEL, ql))
			return -EMSGSIZE;

	return 0;
}

static int
dpll_msg_add_pin_prio(struct sk_buff *msg, struct dpll_pin *pin,
		      struct dpll_pin_ref *ref,
		      struct netlink_ext_ack *extack)
{
	const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
	struct dpll_device *dpll = ref->dpll;
	u32 prio;
	int ret;

	if (!ops->prio_get)
		return 0;
	ret = ops->prio_get(pin, dpll_pin_on_dpll_priv(dpll, pin), dpll,
			    dpll_priv(dpll), &prio, extack);
	if (ret)
		return ret;
	if (nla_put_u32(msg, DPLL_A_PIN_PRIO, prio))
		return -EMSGSIZE;

	return 0;
}

static int
dpll_msg_add_pin_on_dpll_state(struct sk_buff *msg, struct dpll_pin *pin,
			       struct dpll_pin_ref *ref,
			       struct netlink_ext_ack *extack)
{
	const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
	struct dpll_device *dpll = ref->dpll;
	enum dpll_pin_state state;
	int ret;

	if (!ops->state_on_dpll_get)
		return 0;
	ret = ops->state_on_dpll_get(pin, dpll_pin_on_dpll_priv(dpll, pin),
				     dpll, dpll_priv(dpll), &state, extack);
	if (ret)
		return ret;
	if (nla_put_u32(msg, DPLL_A_PIN_STATE, state))
		return -EMSGSIZE;

	return 0;
}

static int
dpll_msg_add_pin_direction(struct sk_buff *msg, struct dpll_pin *pin,
			   struct dpll_pin_ref *ref,
			   struct netlink_ext_ack *extack)
{
	const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
	struct dpll_device *dpll = ref->dpll;
	enum dpll_pin_direction direction;
	int ret;

	ret = ops->direction_get(pin, dpll_pin_on_dpll_priv(dpll, pin), dpll,
				 dpll_priv(dpll), &direction, extack);
	if (ret)
		return ret;
	if (nla_put_u32(msg, DPLL_A_PIN_DIRECTION, direction))
		return -EMSGSIZE;

	return 0;
}

static int
dpll_msg_add_pin_phase_adjust(struct sk_buff *msg, struct dpll_pin *pin,
			      struct dpll_pin_ref *ref,
			      struct netlink_ext_ack *extack)
{
	const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
	struct dpll_device *dpll = ref->dpll;
	s32 phase_adjust;
	int ret;

	if (!ops->phase_adjust_get)
		return 0;
	ret = ops->phase_adjust_get(pin, dpll_pin_on_dpll_priv(dpll, pin),
				    dpll, dpll_priv(dpll),
				    &phase_adjust, extack);
	if (ret)
		return ret;
	if (nla_put_s32(msg, DPLL_A_PIN_PHASE_ADJUST, phase_adjust))
		return -EMSGSIZE;

	return 0;
}

static int
dpll_msg_add_phase_offset(struct sk_buff *msg, struct dpll_pin *pin,
			  struct dpll_pin_ref *ref,
			  struct netlink_ext_ack *extack)
{
	const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
	struct dpll_device *dpll = ref->dpll;
	s64 phase_offset;
	int ret;

	if (!ops->phase_offset_get)
		return 0;
	ret = ops->phase_offset_get(pin, dpll_pin_on_dpll_priv(dpll, pin),
				    dpll, dpll_priv(dpll), &phase_offset,
				    extack);
	if (ret)
		return ret;
	if (nla_put_64bit(msg, DPLL_A_PIN_PHASE_OFFSET, sizeof(phase_offset),
			  &phase_offset, DPLL_A_PIN_PAD))
		return -EMSGSIZE;

	return 0;
}

static int dpll_msg_add_ffo(struct sk_buff *msg, struct dpll_pin *pin,
			    struct dpll_pin_ref *ref,
			    struct netlink_ext_ack *extack)
{
	const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
	struct dpll_device *dpll = ref->dpll;
	s64 ffo;
	int ret;

	if (!ops->ffo_get)
		return 0;
	ret = ops->ffo_get(pin, dpll_pin_on_dpll_priv(dpll, pin),
			   dpll, dpll_priv(dpll), &ffo, extack);
	if (ret) {
		if (ret == -ENODATA)
			return 0;
		return ret;
	}
	return nla_put_sint(msg, DPLL_A_PIN_FRACTIONAL_FREQUENCY_OFFSET, ffo);
}

static int
dpll_msg_add_pin_freq(struct sk_buff *msg, struct dpll_pin *pin,
		      struct dpll_pin_ref *ref, struct netlink_ext_ack *extack)
{
	const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
	struct dpll_device *dpll = ref->dpll;
	struct nlattr *nest;
	int fs, ret;
	u64 freq;

	if (!ops->frequency_get)
		return 0;
	ret = ops->frequency_get(pin, dpll_pin_on_dpll_priv(dpll, pin), dpll,
				 dpll_priv(dpll), &freq, extack);
	if (ret)
		return ret;
	if (nla_put_64bit(msg, DPLL_A_PIN_FREQUENCY, sizeof(freq), &freq,
			  DPLL_A_PIN_PAD))
		return -EMSGSIZE;
	for (fs = 0; fs < pin->prop.freq_supported_num; fs++) {
		nest = nla_nest_start(msg, DPLL_A_PIN_FREQUENCY_SUPPORTED);
		if (!nest)
			return -EMSGSIZE;
		freq = pin->prop.freq_supported[fs].min;
		if (nla_put_64bit(msg, DPLL_A_PIN_FREQUENCY_MIN, sizeof(freq),
				  &freq, DPLL_A_PIN_PAD)) {
			nla_nest_cancel(msg, nest);
			return -EMSGSIZE;
		}
		freq = pin->prop.freq_supported[fs].max;
		if (nla_put_64bit(msg, DPLL_A_PIN_FREQUENCY_MAX, sizeof(freq),
				  &freq, DPLL_A_PIN_PAD)) {
			nla_nest_cancel(msg, nest);
			return -EMSGSIZE;
		}
		nla_nest_end(msg, nest);
	}

	return 0;
}

static int
dpll_msg_add_pin_esync(struct sk_buff *msg, struct dpll_pin *pin,
		       struct dpll_pin_ref *ref, struct netlink_ext_ack *extack)
{
	const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
	struct dpll_device *dpll = ref->dpll;
	struct dpll_pin_esync esync;
	struct nlattr *nest;
	int ret, i;

	if (!ops->esync_get)
		return 0;
	ret = ops->esync_get(pin, dpll_pin_on_dpll_priv(dpll, pin), dpll,
			     dpll_priv(dpll), &esync, extack);
	if (ret == -EOPNOTSUPP)
		return 0;
	else if (ret)
		return ret;
	if (nla_put_64bit(msg, DPLL_A_PIN_ESYNC_FREQUENCY, sizeof(esync.freq),
			  &esync.freq, DPLL_A_PIN_PAD))
		return -EMSGSIZE;
	if (nla_put_u32(msg, DPLL_A_PIN_ESYNC_PULSE, esync.pulse))
		return -EMSGSIZE;
	for (i = 0; i < esync.range_num; i++) {
		nest = nla_nest_start(msg,
				      DPLL_A_PIN_ESYNC_FREQUENCY_SUPPORTED);
		if (!nest)
			return -EMSGSIZE;
		if (nla_put_64bit(msg, DPLL_A_PIN_FREQUENCY_MIN,
				  sizeof(esync.range[i].min),
				  &esync.range[i].min, DPLL_A_PIN_PAD))
			goto nest_cancel;
		if (nla_put_64bit(msg, DPLL_A_PIN_FREQUENCY_MAX,
				  sizeof(esync.range[i].max),
				  &esync.range[i].max, DPLL_A_PIN_PAD))
			goto nest_cancel;
		nla_nest_end(msg, nest);
	}
	return 0;

nest_cancel:
	nla_nest_cancel(msg, nest);
	return -EMSGSIZE;
}

static int
dpll_msg_add_pin_ref_sync(struct sk_buff *msg, struct dpll_pin *pin,
			  struct dpll_pin_ref *ref,
			  struct netlink_ext_ack *extack)
{
	const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
	struct dpll_device *dpll = ref->dpll;
	void *pin_priv, *ref_sync_pin_priv;
	struct dpll_pin *ref_sync_pin;
	enum dpll_pin_state state;
	struct nlattr *nest;
	unsigned long index;
	int ret;

	pin_priv = dpll_pin_on_dpll_priv(dpll, pin);
	xa_for_each(&pin->ref_sync_pins, index, ref_sync_pin) {
		if (!dpll_pin_available(ref_sync_pin))
			continue;
		ref_sync_pin_priv = dpll_pin_on_dpll_priv(dpll, ref_sync_pin);
		if (WARN_ON(!ops->ref_sync_get))
			return -EOPNOTSUPP;
		ret = ops->ref_sync_get(pin, pin_priv, ref_sync_pin,
					ref_sync_pin_priv, &state, extack);
		if (ret)
			return ret;
		nest = nla_nest_start(msg, DPLL_A_PIN_REFERENCE_SYNC);
		if (!nest)
			return -EMSGSIZE;
		if (nla_put_s32(msg, DPLL_A_PIN_ID, ref_sync_pin->id))
			goto nest_cancel;
		if (nla_put_s32(msg, DPLL_A_PIN_STATE, state))
			goto nest_cancel;
		nla_nest_end(msg, nest);
	}
	return 0;

nest_cancel:
	nla_nest_cancel(msg, nest);
	return -EMSGSIZE;
}

static bool dpll_pin_is_freq_supported(struct dpll_pin *pin, u32 freq)
{
	int fs;

	for (fs = 0; fs < pin->prop.freq_supported_num; fs++)
		if (freq >= pin->prop.freq_supported[fs].min &&
		    freq <= pin->prop.freq_supported[fs].max)
			return true;
	return false;
}

static int
dpll_msg_add_pin_parents(struct sk_buff *msg, struct dpll_pin *pin,
			 struct dpll_pin_ref *dpll_ref,
			 struct netlink_ext_ack *extack)
{
	enum dpll_pin_state state;
	struct dpll_pin_ref *ref;
	struct dpll_pin *ppin;
	struct nlattr *nest;
	unsigned long index;
	int ret;

	xa_for_each(&pin->parent_refs, index, ref) {
		const struct dpll_pin_ops *ops = dpll_pin_ops(ref);
		void *parent_priv;

		ppin = ref->pin;
		parent_priv = dpll_pin_on_dpll_priv(dpll_ref->dpll, ppin);
		ret = ops->state_on_pin_get(pin,
					    dpll_pin_on_pin_priv(ppin, pin),
					    ppin, parent_priv, &state, extack);
		if (ret)
			return ret;
		nest = nla_nest_start(msg, DPLL_A_PIN_PARENT_PIN);
		if (!nest)
			return -EMSGSIZE;
		ret = dpll_msg_add_dev_parent_handle(msg, ppin->id);
		if (ret)
			goto nest_cancel;
		if (nla_put_u32(msg, DPLL_A_PIN_STATE, state)) {
			ret = -EMSGSIZE;
			goto nest_cancel;
		}
		nla_nest_end(msg, nest);
	}

	return 0;

nest_cancel:
	nla_nest_cancel(msg, nest);
	return ret;
}

static int
dpll_msg_add_pin_dplls(struct sk_buff *msg, struct dpll_pin *pin,
		       struct netlink_ext_ack *extack)
{
	struct dpll_pin_ref *ref;
	struct nlattr *attr;
	unsigned long index;
	int ret;

	xa_for_each(&pin->dpll_refs, index, ref) {
		attr = nla_nest_start(msg, DPLL_A_PIN_PARENT_DEVICE);
		if (!attr)
			return -EMSGSIZE;
		ret = dpll_msg_add_dev_parent_handle(msg, ref->dpll->id);
		if (ret)
			goto nest_cancel;
		ret = dpll_msg_add_pin_on_dpll_state(msg, pin, ref, extack);
		if (ret)
			goto nest_cancel;
		ret = dpll_msg_add_pin_prio(msg, pin, ref, extack);
		if (ret)
			goto nest_cancel;
		ret = dpll_msg_add_pin_direction(msg, pin, ref, extack);
		if (ret)
			goto nest_cancel;
		ret = dpll_msg_add_phase_offset(msg, pin, ref, extack);
		if (ret)
			goto nest_cancel;
		nla_nest_end(msg, attr);
	}

	return 0;

nest_cancel:
	nla_nest_end(msg, attr);
	return ret;
}

static int
dpll_cmd_pin_get_one(struct sk_buff *msg, struct dpll_pin *pin,
		     struct netlink_ext_ack *extack)
{
	const struct dpll_pin_properties *prop = &pin->prop;
	struct dpll_pin_ref *ref;
	int ret;

	ref = dpll_xa_ref_dpll_first(&pin->dpll_refs);
	ASSERT_NOT_NULL(ref);

	ret = dpll_msg_add_pin_handle(msg, pin);
	if (ret)
		return ret;
	if (nla_put_string(msg, DPLL_A_PIN_MODULE_NAME,
			   module_name(pin->module)))
		return -EMSGSIZE;
	if (nla_put_64bit(msg, DPLL_A_PIN_CLOCK_ID, sizeof(pin->clock_id),
			  &pin->clock_id, DPLL_A_PIN_PAD))
		return -EMSGSIZE;
	if (prop->board_label &&
	    nla_put_string(msg, DPLL_A_PIN_BOARD_LABEL, prop->board_label))
		return -EMSGSIZE;
	if (prop->panel_label &&
	    nla_put_string(msg, DPLL_A_PIN_PANEL_LABEL, prop->panel_label))
		return -EMSGSIZE;
	if (prop->package_label &&
	    nla_put_string(msg, DPLL_A_PIN_PACKAGE_LABEL,
			   prop->package_label))
		return -EMSGSIZE;
	if (nla_put_u32(msg, DPLL_A_PIN_TYPE, prop->type))
		return -EMSGSIZE;
	if (nla_put_u32(msg, DPLL_A_PIN_CAPABILITIES, prop->capabilities))
		return -EMSGSIZE;
	ret = dpll_msg_add_pin_freq(msg, pin, ref, extack);
	if (ret)
		return ret;
	if (nla_put_s32(msg, DPLL_A_PIN_PHASE_ADJUST_MIN,
			prop->phase_range.min))
		return -EMSGSIZE;
	if (nla_put_s32(msg, DPLL_A_PIN_PHASE_ADJUST_MAX,
			prop->phase_range.max))
		return -EMSGSIZE;
	ret = dpll_msg_add_pin_phase_adjust(msg, pin, ref, extack);
	if (ret)
		return ret;
	ret = dpll_msg_add_ffo(msg, pin, ref, extack);
	if (ret)
		return ret;
	ret = dpll_msg_add_pin_esync(msg, pin, ref, extack);
	if (ret)
		return ret;
	if (!xa_empty(&pin->ref_sync_pins))
		ret = dpll_msg_add_pin_ref_sync(msg, pin, ref, extack);
	if (ret)
		return ret;
	if (xa_empty(&pin->parent_refs))
		ret = dpll_msg_add_pin_dplls(msg, pin, extack);
	else
		ret = dpll_msg_add_pin_parents(msg, pin, ref, extack);

	return ret;
}

static int
dpll_device_get_one(struct dpll_device *dpll, struct sk_buff *msg,
		    struct netlink_ext_ack *extack)
{
	int ret;

	ret = dpll_msg_add_dev_handle(msg, dpll);
	if (ret)
		return ret;
	if (nla_put_string(msg, DPLL_A_MODULE_NAME, module_name(dpll->module)))
		return -EMSGSIZE;
	if (nla_put_64bit(msg, DPLL_A_CLOCK_ID, sizeof(dpll->clock_id),
			  &dpll->clock_id, DPLL_A_PAD))
		return -EMSGSIZE;
	ret = dpll_msg_add_temp(msg, dpll, extack);
	if (ret)
		return ret;
	ret = dpll_msg_add_lock_status(msg, dpll, extack);
	if (ret)
		return ret;
	ret = dpll_msg_add_clock_quality_level(msg, dpll, extack);
	if (ret)
		return ret;
	ret = dpll_msg_add_mode(msg, dpll, extack);
	if (ret)
		return ret;
	ret = dpll_msg_add_mode_supported(msg, dpll, extack);
	if (ret)
		return ret;
	if (nla_put_u32(msg, DPLL_A_TYPE, dpll->type))
		return -EMSGSIZE;
	ret = dpll_msg_add_phase_offset_monitor(msg, dpll, extack);
	if (ret)
		return ret;

	return 0;
}

static int
dpll_device_event_send(enum dpll_cmd event, struct dpll_device *dpll)
{
	struct sk_buff *msg;
	int ret = -ENOMEM;
	void *hdr;

	if (WARN_ON(!xa_get_mark(&dpll_device_xa, dpll->id, DPLL_REGISTERED)))
		return -ENODEV;
	msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
	if (!msg)
		return -ENOMEM;
	hdr = genlmsg_put(msg, 0, 0, &dpll_nl_family, 0, event);
	if (!hdr)
		goto err_free_msg;
	ret = dpll_device_get_one(dpll, msg, NULL);
	if (ret)
		goto err_cancel_msg;
	genlmsg_end(msg, hdr);
	genlmsg_multicast(&dpll_nl_family, msg, 0, 0, GFP_KERNEL);

	return 0;

err_cancel_msg:
	genlmsg_cancel(msg, hdr);
err_free_msg:
	nlmsg_free(msg);

	return ret;
}

int dpll_device_create_ntf(struct dpll_device *dpll)
{
	return dpll_device_event_send(DPLL_CMD_DEVICE_CREATE_NTF, dpll);
}

int dpll_device_delete_ntf(struct dpll_device *dpll)
{
	return dpll_device_event_send(DPLL_CMD_DEVICE_DELETE_NTF, dpll);
}

static int
__dpll_device_change_ntf(struct dpll_device *dpll)
{
	return dpll_device_event_send(DPLL_CMD_DEVICE_CHANGE_NTF, dpll);
}

/**
 * dpll_device_change_ntf - notify that the dpll device has been changed
 * @dpll: registered dpll pointer
 *
 * Context: acquires and holds a dpll_lock.
 * Return: 0 if succeeds, error code otherwise.
 */
int dpll_device_change_ntf(struct dpll_device *dpll)
{
	int ret;

	mutex_lock(&dpll_lock);
	ret = __dpll_device_change_ntf(dpll);
	mutex_unlock(&dpll_lock);

	return ret;
}
EXPORT_SYMBOL_GPL(dpll_device_change_ntf);

static int
dpll_pin_event_send(enum dpll_cmd event, struct dpll_pin *pin)
{
	struct sk_buff *msg;
	int ret = -ENOMEM;
	void *hdr;

	if (!dpll_pin_available(pin))
		return -ENODEV;

	msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
	if (!msg)
		return -ENOMEM;

	hdr = genlmsg_put(msg, 0, 0, &dpll_nl_family, 0, event);
	if (!hdr)
		goto err_free_msg;
	ret = dpll_cmd_pin_get_one(msg, pin, NULL);
	if (ret)
		goto err_cancel_msg;
	genlmsg_end(msg, hdr);
	genlmsg_multicast(&dpll_nl_family, msg, 0, 0, GFP_KERNEL);

	return 0;

err_cancel_msg:
	genlmsg_cancel(msg, hdr);
err_free_msg:
	nlmsg_free(msg);

	return ret;
}

int dpll_pin_create_ntf(struct dpll_pin *pin)
{
	return dpll_pin_event_send(DPLL_CMD_PIN_CREATE_NTF, pin);
}

int dpll_pin_delete_ntf(struct dpll_pin *pin)
{
	return dpll_pin_event_send(DPLL_CMD_PIN_DELETE_NTF, pin);
}

int __dpll_pin_change_ntf(struct dpll_pin *pin)
{
	return dpll_pin_event_send(DPLL_CMD_PIN_CHANGE_NTF, pin);
}

/**
 * dpll_pin_change_ntf - notify that the pin has been changed
 * @pin: registered pin pointer
 *
 * Context: acquires and holds a dpll_lock.
 * Return: 0 if succeeds, error code otherwise.
 */
int dpll_pin_change_ntf(struct dpll_pin *pin)
{
	int ret;

	mutex_lock(&dpll_lock);
	ret = __dpll_pin_change_ntf(pin);
	mutex_unlock(&dpll_lock);

	return ret;
}
EXPORT_SYMBOL_GPL(dpll_pin_change_ntf);

static int
dpll_phase_offset_monitor_set(struct dpll_device *dpll, struct nlattr *a,
			      struct netlink_ext_ack *extack)
{
	const struct dpll_device_ops *ops = dpll_device_ops(dpll);
	enum dpll_feature_state state = nla_get_u32(a), old_state;
	int ret;

	if (!(ops->phase_offset_monitor_set && ops->phase_offset_monitor_get)) {
		NL_SET_ERR_MSG_ATTR(extack, a, "dpll device not capable of phase offset monitor");
		return -EOPNOTSUPP;
	}
	ret = ops->phase_offset_monitor_get(dpll, dpll_priv(dpll), &old_state,
					    extack);
	if (ret) {
		NL_SET_ERR_MSG(extack, "unable to get current state of phase offset monitor");
		return ret;
	}
	if (state == old_state)
		return 0;

	return ops->phase_offset_monitor_set(dpll, dpll_priv(dpll), state,
					     extack);
}

static int
dpll_pin_freq_set(struct dpll_pin *pin, struct nlattr *a,
		  struct netlink_ext_ack *extack)
{
	u64 freq = nla_get_u64(a), old_freq;
	struct dpll_pin_ref *ref, *failed;
	const struct dpll_pin_ops *ops;
	struct dpll_device *dpll;
	unsigned long i;
	int ret;

	if (!dpll_pin_is_freq_supported(pin, freq)) {
		NL_SET_ERR_MSG_ATTR(extack, a, "frequency is not supported by the device");
		return -EINVAL;
	}

	xa_for_each(&pin->dpll_refs, i, ref) {
		ops = dpll_pin_ops(ref);
		if (!ops->frequency_set || !ops->frequency_get) {
			NL_SET_ERR_MSG(extack, "frequency set not supported by the device");
			return -EOPNOTSUPP;
		}
	}
	ref = dpll_xa_ref_dpll_first(&pin->dpll_refs);
	ops = dpll_pin_ops(ref);
	dpll = ref->dpll;
	ret = ops->frequency_get(pin, dpll_pin_on_dpll_priv(dpll, pin), dpll,
				 dpll_priv(dpll), &old_freq, extack);
	if (ret) {
		NL_SET_ERR_MSG(extack, "unable to get old frequency value");
		return ret;
	}
	if (freq == old_freq)
		return 0;

	xa_for_each(&pin->dpll_refs, i, ref) {
		ops = dpll_pin_ops(ref);
		dpll = ref->dpll;
		ret = ops->frequency_set(pin, dpll_pin_on_dpll_priv(dpll, pin),
					 dpll, dpll_priv(dpll), freq, extack);
		if (ret) {
			failed = ref;
			NL_SET_ERR_MSG_FMT(extack, "frequency set failed for dpll_id:%u",
					   dpll->id);
			goto rollback;
		}
	}
	__dpll_pin_change_ntf(pin);

	return 0;

rollback:
	xa_for_each(&pin->dpll_refs, i, ref) {
		if (ref == failed)
			break;
		ops = dpll_pin_ops(ref);
		dpll = ref->dpll;
		if (ops->frequency_set(pin, dpll_pin_on_dpll_priv(dpll, pin),
				       dpll, dpll_priv(dpll), old_freq, extack))
			NL_SET_ERR_MSG(extack, "set frequency rollback failed");
	}
	return ret;
}

static int
dpll_pin_esync_set(struct dpll_pin *pin, struct nlattr *a,
		   struct netlink_ext_ack *extack)
{
	struct dpll_pin_ref *ref, *failed;
	const struct dpll_pin_ops *ops;
	struct dpll_pin_esync esync;
	u64 freq = nla_get_u64(a);
	struct dpll_device *dpll;
	bool supported = false;
	unsigned long i;
	int ret;

	xa_for_each(&pin->dpll_refs, i, ref) {
		ops = dpll_pin_ops(ref);
		if (!ops->esync_set || !ops->esync_get) {
			NL_SET_ERR_MSG(extack,
				       "embedded sync feature is not supported by this device");
			return -EOPNOTSUPP;
		}
	}
	ref = dpll_xa_ref_dpll_first(&pin->dpll_refs);
	ops = dpll_pin_ops(ref);
	dpll = ref->dpll;
	ret = ops->esync_get(pin, dpll_pin_on_dpll_priv(dpll, pin), dpll,
			     dpll_priv(dpll), &esync, extack);
	if (ret) {
		NL_SET_ERR_MSG(extack, "unable to get current embedded sync frequency value");
		return ret;
	}
	if (freq == esync.freq)
		return 0;
	for (i = 0; i < esync.range_num; i++)
		if (freq <= esync.range[i].max && freq >= esync.range[i].min)
			supported = true;
	if (!supported) {
		NL_SET_ERR_MSG_ATTR(extack, a,
				    "requested embedded sync frequency value is not supported by this device");
		return -EINVAL;
	}

	xa_for_each(&pin->dpll_refs, i, ref) {
		void *pin_dpll_priv;

		ops = dpll_pin_ops(ref);
		dpll = ref->dpll;
		pin_dpll_priv = dpll_pin_on_dpll_priv(dpll, pin);
		ret = ops->esync_set(pin, pin_dpll_priv, dpll, dpll_priv(dpll),
				      freq, extack);
		if (ret) {
			failed = ref;
			NL_SET_ERR_MSG_FMT(extack,
					   "embedded sync frequency set failed for dpll_id: %u",
					   dpll->id);
			goto rollback;
		}
	}
	__dpll_pin_change_ntf(pin);

	return 0;

rollback:
	xa_for_each(&pin->dpll_refs, i, ref) {
		void *pin_dpll_priv;

		if (ref == failed)
			break;
		ops = dpll_pin_ops(ref);
		dpll = ref->dpll;
		pin_dpll_priv = dpll_pin_on_dpll_priv(dpll, pin);
		if (ops->esync_set(pin, pin_dpll_priv, dpll, dpll_priv(dpll),
				   esync.freq, extack))
			NL_SET_ERR_MSG(extack, "set embedded sync frequency rollback failed");
	}
	return ret;
}

static int
dpll_pin_ref_sync_state_set(struct dpll_pin *pin,
			    unsigned long ref_sync_pin_idx,
			    const enum dpll_pin_state state,
			    struct netlink_ext_ack *extack)

{
	struct dpll_pin_ref *ref, *failed;
	const struct dpll_pin_ops *ops;
	enum dpll_pin_state old_state;
	struct dpll_pin *ref_sync_pin;
	struct dpll_device *dpll;
	unsigned long i;
	int ret;

	ref_sync_pin = xa_find(&pin->ref_sync_pins, &ref_sync_pin_idx,
			       ULONG_MAX, XA_PRESENT);
	if (!ref_sync_pin) {
		NL_SET_ERR_MSG(extack, "reference sync pin not found");
		return -EINVAL;
	}
	if (!dpll_pin_available(ref_sync_pin)) {
		NL_SET_ERR_MSG(extack, "reference sync pin not available");
		return -EINVAL;
	}
	ref = dpll_xa_ref_dpll_first(&pin->dpll_refs);
	ASSERT_NOT_NULL(ref);
	ops = dpll_pin_ops(ref);
	if (!ops->ref_sync_set || !ops->ref_sync_get) {
		NL_SET_ERR_MSG(extack, "reference sync not supported by this pin");
		return -EOPNOTSUPP;
	}
	dpll = ref->dpll;
	ret = ops->ref_sync_get(pin, dpll_pin_on_dpll_priv(dpll, pin),
				ref_sync_pin,
				dpll_pin_on_dpll_priv(dpll, ref_sync_pin),
				&old_state, extack);
	if (ret) {
		NL_SET_ERR_MSG(extack, "unable to get old reference sync state");
		return ret;
	}
	if (state == old_state)
		return 0;
	xa_for_each(&pin->dpll_refs, i, ref) {
		ops = dpll_pin_ops(ref);
		dpll = ref->dpll;
		ret = ops->ref_sync_set(pin, dpll_pin_on_dpll_priv(dpll, pin),
					ref_sync_pin,
					dpll_pin_on_dpll_priv(dpll,
							      ref_sync_pin),
					state, extack);
		if (ret) {
			failed = ref;
			NL_SET_ERR_MSG_FMT(extack, "reference sync set failed for dpll_id:%u",
					   dpll->id);
			goto rollback;
		}
	}
	__dpll_pin_change_ntf(pin);

	return 0;

rollback:
	xa_for_each(&pin->dpll_refs, i, ref) {
		if (ref == failed)
			break;
		ops = dpll_pin_ops(ref);
		dpll = ref->dpll;
		if (ops->ref_sync_set(pin, dpll_pin_on_dpll_priv(dpll, pin),
				      ref_sync_pin,
				      dpll_pin_on_dpll_priv(dpll, ref_sync_pin),
				      old_state, extack))
			NL_SET_ERR_MSG(extack, "set reference sync rollback failed");
	}
	return ret;
}

static int
dpll_pin_ref_sync_set(struct dpll_pin *pin, struct nlattr *nest,
		      struct netlink_ext_ack *extack)
{
	struct nlattr *tb[DPLL_A_PIN_MAX + 1];
	enum dpll_pin_state state;
	u32 sync_pin_id;

	nla_parse_nested(tb, DPLL_A_PIN_MAX, nest,
			 dpll_reference_sync_nl_policy, extack);
	if (!tb[DPLL_A_PIN_ID]) {
		NL_SET_ERR_MSG(extack, "sync pin id expected");
		return -EINVAL;
	}
	sync_pin_id = nla_get_u32(tb[DPLL_A_PIN_ID]);

	if (!tb[DPLL_A_PIN_STATE]) {
		NL_SET_ERR_MSG(extack, "sync pin state expected");
		return -EINVAL;
	}
	state = nla_get_u32(tb[DPLL_A_PIN_STATE]);

	return dpll_pin_ref_sync_state_set(pin, sync_pin_id, state, extack);
}

static int
dpll_pin_on_pin_state_set(struct dpll_pin *pin, u32 parent_idx,
			  enum dpll_pin_state state,
			  struct netlink_ext_ack *extack)
{
	struct dpll_pin_ref *parent_ref;
	const struct dpll_pin_ops *ops;
	struct dpll_pin_ref *dpll_ref;
	void *pin_priv, *parent_priv;
	struct dpll_pin *parent;
	unsigned long i;
	int ret;

	if (!(DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE &
	      pin->prop.capabilities)) {
		NL_SET_ERR_MSG(extack, "state changing is not allowed");
		return -EOPNOTSUPP;
	}
	parent = xa_load(&dpll_pin_xa, parent_idx);
	if (!parent)
		return -EINVAL;
	parent_ref = xa_load(&pin->parent_refs, parent->pin_idx);
	if (!parent_ref)
		return -EINVAL;
	xa_for_each(&parent->dpll_refs, i, dpll_ref) {
		ops = dpll_pin_ops(parent_ref);
		if (!ops->state_on_pin_set)
			return -EOPNOTSUPP;
		pin_priv = dpll_pin_on_pin_priv(parent, pin);
		parent_priv = dpll_pin_on_dpll_priv(dpll_ref->dpll, parent);
		ret = ops->state_on_pin_set(pin, pin_priv, parent, parent_priv,
					    state, extack);
		if (ret)
			return ret;
	}
	__dpll_pin_change_ntf(pin);

	return 0;
}

static int
dpll_pin_state_set(struct dpll_device *dpll, struct dpll_pin *pin,
		   enum dpll_pin_state state,
		   struct netlink_ext_ack *extack)
{
	const struct dpll_pin_ops *ops;
	struct dpll_pin_ref *ref;
	int ret;

	if (!(DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE &
	      pin->prop.capabilities)) {
		NL_SET_ERR_MSG(extack, "state changing is not allowed");
		return -EOPNOTSUPP;
	}
	ref = xa_load(&pin->dpll_refs, dpll->id);
	ASSERT_NOT_NULL(ref);
	ops = dpll_pin_ops(ref);
	if (!ops->state_on_dpll_set)
		return -EOPNOTSUPP;
	ret = ops->state_on_dpll_set(pin, dpll_pin_on_dpll_priv(dpll, pin),
				     dpll, dpll_priv(dpll), state, extack);
	if (ret)
		return ret;
	__dpll_pin_change_ntf(pin);

	return 0;
}

static int
dpll_pin_prio_set(struct dpll_device *dpll, struct dpll_pin *pin,
		  u32 prio, struct netlink_ext_ack *extack)
{
	const struct dpll_pin_ops *ops;
	struct dpll_pin_ref *ref;
	int ret;

	if (!(DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE &
	      pin->prop.capabilities)) {
		NL_SET_ERR_MSG(extack, "prio changing is not allowed");
		return -EOPNOTSUPP;
	}
	ref = xa_load(&pin->dpll_refs, dpll->id);
	ASSERT_NOT_NULL(ref);
	ops = dpll_pin_ops(ref);
	if (!ops->prio_set)
		return -EOPNOTSUPP;
	ret = ops->prio_set(pin, dpll_pin_on_dpll_priv(dpll, pin), dpll,
			    dpll_priv(dpll), prio, extack);
	if (ret)
		return ret;
	__dpll_pin_change_ntf(pin);

	return 0;
}

static int
dpll_pin_direction_set(struct dpll_pin *pin, struct dpll_device *dpll,
		       enum dpll_pin_direction direction,
		       struct netlink_ext_ack *extack)
{
	const struct dpll_pin_ops *ops;
	struct dpll_pin_ref *ref;
	int ret;

	if (!(DPLL_PIN_CAPABILITIES_DIRECTION_CAN_CHANGE &
	      pin->prop.capabilities)) {
		NL_SET_ERR_MSG(extack, "direction changing is not allowed");
		return -EOPNOTSUPP;
	}
	ref = xa_load(&pin->dpll_refs, dpll->id);
	ASSERT_NOT_NULL(ref);
	ops = dpll_pin_ops(ref);
	if (!ops->direction_set)
		return -EOPNOTSUPP;
	ret = ops->direction_set(pin, dpll_pin_on_dpll_priv(dpll, pin),
				 dpll, dpll_priv(dpll), direction, extack);
	if (ret)
		return ret;
	__dpll_pin_change_ntf(pin);

	return 0;
}

static int
dpll_pin_phase_adj_set(struct dpll_pin *pin, struct nlattr *phase_adj_attr,
		       struct netlink_ext_ack *extack)
{
	struct dpll_pin_ref *ref, *failed;
	const struct dpll_pin_ops *ops;
	s32 phase_adj, old_phase_adj;
	struct dpll_device *dpll;
	unsigned long i;
	int ret;

	phase_adj = nla_get_s32(phase_adj_attr);
	if (phase_adj > pin->prop.phase_range.max ||
	    phase_adj < pin->prop.phase_range.min) {
		NL_SET_ERR_MSG_ATTR(extack, phase_adj_attr,
				    "phase adjust value not supported");
		return -EINVAL;
	}

	xa_for_each(&pin->dpll_refs, i, ref) {
		ops = dpll_pin_ops(ref);
		if (!ops->phase_adjust_set || !ops->phase_adjust_get) {
			NL_SET_ERR_MSG(extack, "phase adjust not supported");
			return -EOPNOTSUPP;
		}
	}
	ref = dpll_xa_ref_dpll_first(&pin->dpll_refs);
	ops = dpll_pin_ops(ref);
	dpll = ref->dpll;
	ret = ops->phase_adjust_get(pin, dpll_pin_on_dpll_priv(dpll, pin),
				    dpll, dpll_priv(dpll), &old_phase_adj,
				    extack);
	if (ret) {
		NL_SET_ERR_MSG(extack, "unable to get old phase adjust value");
		return ret;
	}
	if (phase_adj == old_phase_adj)
		return 0;

	xa_for_each(&pin->dpll_refs, i, ref) {
		ops = dpll_pin_ops(ref);
		dpll = ref->dpll;
		ret = ops->phase_adjust_set(pin,
					    dpll_pin_on_dpll_priv(dpll, pin),
					    dpll, dpll_priv(dpll), phase_adj,
					    extack);
		if (ret) {
			failed = ref;
			NL_SET_ERR_MSG_FMT(extack,
					   "phase adjust set failed for dpll_id:%u",
					   dpll->id);
			goto rollback;
		}
	}
	__dpll_pin_change_ntf(pin);

	return 0;

rollback:
	xa_for_each(&pin->dpll_refs, i, ref) {
		if (ref == failed)
			break;
		ops = dpll_pin_ops(ref);
		dpll = ref->dpll;
		if (ops->phase_adjust_set(pin, dpll_pin_on_dpll_priv(dpll, pin),
					  dpll, dpll_priv(dpll), old_phase_adj,
					  extack))
			NL_SET_ERR_MSG(extack, "set phase adjust rollback failed");
	}
	return ret;
}

static int
dpll_pin_parent_device_set(struct dpll_pin *pin, struct nlattr *parent_nest,
			   struct netlink_ext_ack *extack)
{
	struct nlattr *tb[DPLL_A_PIN_MAX + 1];
	enum dpll_pin_direction direction;
	enum dpll_pin_state state;
	struct dpll_pin_ref *ref;
	struct dpll_device *dpll;
	u32 pdpll_idx, prio;
	int ret;

	nla_parse_nested(tb, DPLL_A_PIN_MAX, parent_nest,
			 dpll_pin_parent_device_nl_policy, extack);
	if (!tb[DPLL_A_PIN_PARENT_ID]) {
		NL_SET_ERR_MSG(extack, "device parent id expected");
		return -EINVAL;
	}
	pdpll_idx = nla_get_u32(tb[DPLL_A_PIN_PARENT_ID]);
	dpll = xa_load(&dpll_device_xa, pdpll_idx);
	if (!dpll) {
		NL_SET_ERR_MSG(extack, "parent device not found");
		return -EINVAL;
	}
	ref = xa_load(&pin->dpll_refs, dpll->id);
	if (!ref) {
		NL_SET_ERR_MSG(extack, "pin not connected to given parent device");
		return -EINVAL;
	}
	if (tb[DPLL_A_PIN_STATE]) {
		state = nla_get_u32(tb[DPLL_A_PIN_STATE]);
		ret = dpll_pin_state_set(dpll, pin, state, extack);
		if (ret)
			return ret;
	}
	if (tb[DPLL_A_PIN_PRIO]) {
		prio = nla_get_u32(tb[DPLL_A_PIN_PRIO]);
		ret = dpll_pin_prio_set(dpll, pin, prio, extack);
		if (ret)
			return ret;
	}
	if (tb[DPLL_A_PIN_DIRECTION]) {
		direction = nla_get_u32(tb[DPLL_A_PIN_DIRECTION]);
		ret = dpll_pin_direction_set(pin, dpll, direction, extack);
		if (ret)
			return ret;
	}
	return 0;
}

static int
dpll_pin_parent_pin_set(struct dpll_pin *pin, struct nlattr *parent_nest,
			struct netlink_ext_ack *extack)
{
	struct nlattr *tb[DPLL_A_PIN_MAX + 1];
	u32 ppin_idx;
	int ret;

	nla_parse_nested(tb, DPLL_A_PIN_MAX, parent_nest,
			 dpll_pin_parent_pin_nl_policy, extack);
	if (!tb[DPLL_A_PIN_PARENT_ID]) {
		NL_SET_ERR_MSG(extack, "device parent id expected");
		return -EINVAL;
	}
	ppin_idx = nla_get_u32(tb[DPLL_A_PIN_PARENT_ID]);

	if (tb[DPLL_A_PIN_STATE]) {
		enum dpll_pin_state state = nla_get_u32(tb[DPLL_A_PIN_STATE]);

		ret = dpll_pin_on_pin_state_set(pin, ppin_idx, state, extack);
		if (ret)
			return ret;
	}

	return 0;
}

static int
dpll_pin_set_from_nlattr(struct dpll_pin *pin, struct genl_info *info)
{
	struct nlattr *a;
	int rem, ret;

	nla_for_each_attr(a, genlmsg_data(info->genlhdr),
			  genlmsg_len(info->genlhdr), rem) {
		switch (nla_type(a)) {
		case DPLL_A_PIN_FREQUENCY:
			ret = dpll_pin_freq_set(pin, a, info->extack);
			if (ret)
				return ret;
			break;
		case DPLL_A_PIN_PHASE_ADJUST:
			ret = dpll_pin_phase_adj_set(pin, a, info->extack);
			if (ret)
				return ret;
			break;
		case DPLL_A_PIN_PARENT_DEVICE:
			ret = dpll_pin_parent_device_set(pin, a, info->extack);
			if (ret)
				return ret;
			break;
		case DPLL_A_PIN_PARENT_PIN:
			ret = dpll_pin_parent_pin_set(pin, a, info->extack);
			if (ret)
				return ret;
			break;
		case DPLL_A_PIN_ESYNC_FREQUENCY:
			ret = dpll_pin_esync_set(pin, a, info->extack);
			if (ret)
				return ret;
			break;
		case DPLL_A_PIN_REFERENCE_SYNC:
			ret = dpll_pin_ref_sync_set(pin, a, info->extack);
			if (ret)
				return ret;
			break;
		}
	}

	return 0;
}

static struct dpll_pin *
dpll_pin_find(u64 clock_id, struct nlattr *mod_name_attr,
	      enum dpll_pin_type type, struct nlattr *board_label,
	      struct nlattr *panel_label, struct nlattr *package_label,
	      struct netlink_ext_ack *extack)
{
	bool board_match, panel_match, package_match;
	struct dpll_pin *pin_match = NULL, *pin;
	const struct dpll_pin_properties *prop;
	bool cid_match, mod_match, type_match;
	unsigned long i;

	xa_for_each_marked(&dpll_pin_xa, i, pin, DPLL_REGISTERED) {
		prop = &pin->prop;
		cid_match = clock_id ? pin->clock_id == clock_id : true;
		mod_match = mod_name_attr && module_name(pin->module) ?
			!nla_strcmp(mod_name_attr,
				    module_name(pin->module)) : true;
		type_match = type ? prop->type == type : true;
		board_match = board_label ? (prop->board_label ?
			!nla_strcmp(board_label, prop->board_label) : false) :
			true;
		panel_match = panel_label ? (prop->panel_label ?
			!nla_strcmp(panel_label, prop->panel_label) : false) :
			true;
		package_match = package_label ? (prop->package_label ?
			!nla_strcmp(package_label, prop->package_label) :
			false) : true;
		if (cid_match && mod_match && type_match && board_match &&
		    panel_match && package_match) {
			if (pin_match) {
				NL_SET_ERR_MSG(extack, "multiple matches");
				return ERR_PTR(-EINVAL);
			}
			pin_match = pin;
		}
	}
	if (!pin_match) {
		NL_SET_ERR_MSG(extack, "not found");
		return ERR_PTR(-ENODEV);
	}
	return pin_match;
}

static struct dpll_pin *dpll_pin_find_from_nlattr(struct genl_info *info)
{
	struct nlattr *attr, *mod_name_attr = NULL, *board_label_attr = NULL,
		*panel_label_attr = NULL, *package_label_attr = NULL;
	enum dpll_pin_type type = 0;
	u64 clock_id = 0;
	int rem = 0;

	nla_for_each_attr(attr, genlmsg_data(info->genlhdr),
			  genlmsg_len(info->genlhdr), rem) {
		switch (nla_type(attr)) {
		case DPLL_A_PIN_CLOCK_ID:
			if (clock_id)
				goto duplicated_attr;
			clock_id = nla_get_u64(attr);
			break;
		case DPLL_A_PIN_MODULE_NAME:
			if (mod_name_attr)
				goto duplicated_attr;
			mod_name_attr = attr;
			break;
		case DPLL_A_PIN_TYPE:
			if (type)
				goto duplicated_attr;
			type = nla_get_u32(attr);
		break;
		case DPLL_A_PIN_BOARD_LABEL:
			if (board_label_attr)
				goto duplicated_attr;
			board_label_attr = attr;
		break;
		case DPLL_A_PIN_PANEL_LABEL:
			if (panel_label_attr)
				goto duplicated_attr;
			panel_label_attr = attr;
		break;
		case DPLL_A_PIN_PACKAGE_LABEL:
			if (package_label_attr)
				goto duplicated_attr;
			package_label_attr = attr;
		break;
		default:
			break;
		}
	}
	if (!(clock_id  || mod_name_attr || board_label_attr ||
	      panel_label_attr || package_label_attr)) {
		NL_SET_ERR_MSG(info->extack, "missing attributes");
		return ERR_PTR(-EINVAL);
	}
	return dpll_pin_find(clock_id, mod_name_attr, type, board_label_attr,
			     panel_label_attr, package_label_attr,
			     info->extack);
duplicated_attr:
	NL_SET_ERR_MSG(info->extack, "duplicated attribute");
	return ERR_PTR(-EINVAL);
}

int dpll_nl_pin_id_get_doit(struct sk_buff *skb, struct genl_info *info)
{
	struct dpll_pin *pin;
	struct sk_buff *msg;
	struct nlattr *hdr;
	int ret;

	msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
	if (!msg)
		return -ENOMEM;
	hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0,
				DPLL_CMD_PIN_ID_GET);
	if (!hdr) {
		nlmsg_free(msg);
		return -EMSGSIZE;
	}
	pin = dpll_pin_find_from_nlattr(info);
	if (!IS_ERR(pin)) {
		if (!dpll_pin_available(pin)) {
			nlmsg_free(msg);
			return -ENODEV;
		}
		ret = dpll_msg_add_pin_handle(msg, pin);
		if (ret) {
			nlmsg_free(msg);
			return ret;
		}
	}
	genlmsg_end(msg, hdr);

	return genlmsg_reply(msg, info);
}

int dpll_nl_pin_get_doit(struct sk_buff *skb, struct genl_info *info)
{
	struct dpll_pin *pin = info->user_ptr[0];
	struct sk_buff *msg;
	struct nlattr *hdr;
	int ret;

	if (!pin)
		return -ENODEV;
	msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
	if (!msg)
		return -ENOMEM;
	hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0,
				DPLL_CMD_PIN_GET);
	if (!hdr) {
		nlmsg_free(msg);
		return -EMSGSIZE;
	}
	ret = dpll_cmd_pin_get_one(msg, pin, info->extack);
	if (ret) {
		nlmsg_free(msg);
		return ret;
	}
	genlmsg_end(msg, hdr);

	return genlmsg_reply(msg, info);
}

int dpll_nl_pin_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
{
	struct dpll_dump_ctx *ctx = dpll_dump_context(cb);
	struct dpll_pin *pin;
	struct nlattr *hdr;
	unsigned long i;
	int ret = 0;

	mutex_lock(&dpll_lock);
	xa_for_each_marked_start(&dpll_pin_xa, i, pin, DPLL_REGISTERED,
				 ctx->idx) {
		if (!dpll_pin_available(pin))
			continue;
		hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
				  cb->nlh->nlmsg_seq,
				  &dpll_nl_family, NLM_F_MULTI,
				  DPLL_CMD_PIN_GET);
		if (!hdr) {
			ret = -EMSGSIZE;
			break;
		}
		ret = dpll_cmd_pin_get_one(skb, pin, cb->extack);
		if (ret) {
			genlmsg_cancel(skb, hdr);
			break;
		}
		genlmsg_end(skb, hdr);
	}
	mutex_unlock(&dpll_lock);

	if (ret == -EMSGSIZE) {
		ctx->idx = i;
		return skb->len;
	}
	return ret;
}

int dpll_nl_pin_set_doit(struct sk_buff *skb, struct genl_info *info)
{
	struct dpll_pin *pin = info->user_ptr[0];

	return dpll_pin_set_from_nlattr(pin, info);
}

static struct dpll_device *
dpll_device_find(u64 clock_id, struct nlattr *mod_name_attr,
		 enum dpll_type type, struct netlink_ext_ack *extack)
{
	struct dpll_device *dpll_match = NULL, *dpll;
	bool cid_match, mod_match, type_match;
	unsigned long i;

	xa_for_each_marked(&dpll_device_xa, i, dpll, DPLL_REGISTERED) {
		cid_match = clock_id ? dpll->clock_id == clock_id : true;
		mod_match = mod_name_attr ? (module_name(dpll->module) ?
			!nla_strcmp(mod_name_attr,
				    module_name(dpll->module)) : false) : true;
		type_match = type ? dpll->type == type : true;
		if (cid_match && mod_match && type_match) {
			if (dpll_match) {
				NL_SET_ERR_MSG(extack, "multiple matches");
				return ERR_PTR(-EINVAL);
			}
			dpll_match = dpll;
		}
	}
	if (!dpll_match) {
		NL_SET_ERR_MSG(extack, "not found");
		return ERR_PTR(-ENODEV);
	}

	return dpll_match;
}

static struct dpll_device *
dpll_device_find_from_nlattr(struct genl_info *info)
{
	struct nlattr *attr, *mod_name_attr = NULL;
	enum dpll_type type = 0;
	u64 clock_id = 0;
	int rem = 0;

	nla_for_each_attr(attr, genlmsg_data(info->genlhdr),
			  genlmsg_len(info->genlhdr), rem) {
		switch (nla_type(attr)) {
		case DPLL_A_CLOCK_ID:
			if (clock_id)
				goto duplicated_attr;
			clock_id = nla_get_u64(attr);
			break;
		case DPLL_A_MODULE_NAME:
			if (mod_name_attr)
				goto duplicated_attr;
			mod_name_attr = attr;
			break;
		case DPLL_A_TYPE:
			if (type)
				goto duplicated_attr;
			type = nla_get_u32(attr);
			break;
		default:
			break;
		}
	}
	if (!clock_id && !mod_name_attr && !type) {
		NL_SET_ERR_MSG(info->extack, "missing attributes");
		return ERR_PTR(-EINVAL);
	}
	return dpll_device_find(clock_id, mod_name_attr, type, info->extack);
duplicated_attr:
	NL_SET_ERR_MSG(info->extack, "duplicated attribute");
	return ERR_PTR(-EINVAL);
}

int dpll_nl_device_id_get_doit(struct sk_buff *skb, struct genl_info *info)
{
	struct dpll_device *dpll;
	struct sk_buff *msg;
	struct nlattr *hdr;
	int ret;

	msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
	if (!msg)
		return -ENOMEM;
	hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0,
				DPLL_CMD_DEVICE_ID_GET);
	if (!hdr) {
		nlmsg_free(msg);
		return -EMSGSIZE;
	}

	dpll = dpll_device_find_from_nlattr(info);
	if (!IS_ERR(dpll)) {
		ret = dpll_msg_add_dev_handle(msg, dpll);
		if (ret) {
			nlmsg_free(msg);
			return ret;
		}
	}
	genlmsg_end(msg, hdr);

	return genlmsg_reply(msg, info);
}

int dpll_nl_device_get_doit(struct sk_buff *skb, struct genl_info *info)
{
	struct dpll_device *dpll = info->user_ptr[0];
	struct sk_buff *msg;
	struct nlattr *hdr;
	int ret;

	msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
	if (!msg)
		return -ENOMEM;
	hdr = genlmsg_put_reply(msg, info, &dpll_nl_family, 0,
				DPLL_CMD_DEVICE_GET);
	if (!hdr) {
		nlmsg_free(msg);
		return -EMSGSIZE;
	}

	ret = dpll_device_get_one(dpll, msg, info->extack);
	if (ret) {
		nlmsg_free(msg);
		return ret;
	}
	genlmsg_end(msg, hdr);

	return genlmsg_reply(msg, info);
}

static int
dpll_set_from_nlattr(struct dpll_device *dpll, struct genl_info *info)
{
	int ret;

	if (info->attrs[DPLL_A_PHASE_OFFSET_MONITOR]) {
		struct nlattr *a = info->attrs[DPLL_A_PHASE_OFFSET_MONITOR];

		ret = dpll_phase_offset_monitor_set(dpll, a, info->extack);
		if (ret)
			return ret;
	}

	return 0;
}

int dpll_nl_device_set_doit(struct sk_buff *skb, struct genl_info *info)
{
	struct dpll_device *dpll = info->user_ptr[0];

	return dpll_set_from_nlattr(dpll, info);
}

int dpll_nl_device_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
{
	struct dpll_dump_ctx *ctx = dpll_dump_context(cb);
	struct dpll_device *dpll;
	struct nlattr *hdr;
	unsigned long i;
	int ret = 0;

	mutex_lock(&dpll_lock);
	xa_for_each_marked_start(&dpll_device_xa, i, dpll, DPLL_REGISTERED,
				 ctx->idx) {
		hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
				  cb->nlh->nlmsg_seq, &dpll_nl_family,
				  NLM_F_MULTI, DPLL_CMD_DEVICE_GET);
		if (!hdr) {
			ret = -EMSGSIZE;
			break;
		}
		ret = dpll_device_get_one(dpll, skb, cb->extack);
		if (ret) {
			genlmsg_cancel(skb, hdr);
			break;
		}
		genlmsg_end(skb, hdr);
	}
	mutex_unlock(&dpll_lock);

	if (ret == -EMSGSIZE) {
		ctx->idx = i;
		return skb->len;
	}
	return ret;
}

int dpll_pre_doit(const struct genl_split_ops *ops, struct sk_buff *skb,
		  struct genl_info *info)
{
	u32 id;

	if (GENL_REQ_ATTR_CHECK(info, DPLL_A_ID))
		return -EINVAL;

	mutex_lock(&dpll_lock);
	id = nla_get_u32(info->attrs[DPLL_A_ID]);
	info->user_ptr[0] = dpll_device_get_by_id(id);
	if (!info->user_ptr[0]) {
		NL_SET_ERR_MSG(info->extack, "device not found");
		goto unlock;
	}
	return 0;
unlock:
	mutex_unlock(&dpll_lock);
	return -ENODEV;
}

void dpll_post_doit(const struct genl_split_ops *ops, struct sk_buff *skb,
		    struct genl_info *info)
{
	mutex_unlock(&dpll_lock);
}

int
dpll_lock_doit(const struct genl_split_ops *ops, struct sk_buff *skb,
	       struct genl_info *info)
{
	mutex_lock(&dpll_lock);

	return 0;
}

void
dpll_unlock_doit(const struct genl_split_ops *ops, struct sk_buff *skb,
		 struct genl_info *info)
{
	mutex_unlock(&dpll_lock);
}

int dpll_pin_pre_doit(const struct genl_split_ops *ops, struct sk_buff *skb,
		      struct genl_info *info)
{
	int ret;

	mutex_lock(&dpll_lock);
	if (GENL_REQ_ATTR_CHECK(info, DPLL_A_PIN_ID)) {
		ret = -EINVAL;
		goto unlock_dev;
	}
	info->user_ptr[0] = xa_load(&dpll_pin_xa,
				    nla_get_u32(info->attrs[DPLL_A_PIN_ID]));
	if (!info->user_ptr[0] ||
	    !dpll_pin_available(info->user_ptr[0])) {
		NL_SET_ERR_MSG(info->extack, "pin not found");
		ret = -ENODEV;
		goto unlock_dev;
	}

	return 0;

unlock_dev:
	mutex_unlock(&dpll_lock);
	return ret;
}

void dpll_pin_post_doit(const struct genl_split_ops *ops, struct sk_buff *skb,
			struct genl_info *info)
{
	mutex_unlock(&dpll_lock);
}
