// SPDX-License-Identifier: GPL-2.0
/*
 *  dpll_core.c - DPLL subsystem kernel-space interface implementation.
 *
 *  Copyright (c) 2023 Meta Platforms, Inc. and affiliates
 *  Copyright (c) 2023 Intel Corporation.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/device.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/string.h>

#include "dpll_core.h"
#include "dpll_netlink.h"

/* Mutex lock to protect DPLL subsystem devices and pins */
DEFINE_MUTEX(dpll_lock);

DEFINE_XARRAY_FLAGS(dpll_device_xa, XA_FLAGS_ALLOC);
DEFINE_XARRAY_FLAGS(dpll_pin_xa, XA_FLAGS_ALLOC);

static u32 dpll_device_xa_id;
static u32 dpll_pin_xa_id;

#define ASSERT_DPLL_REGISTERED(d)	\
	WARN_ON_ONCE(!xa_get_mark(&dpll_device_xa, (d)->id, DPLL_REGISTERED))
#define ASSERT_DPLL_NOT_REGISTERED(d)	\
	WARN_ON_ONCE(xa_get_mark(&dpll_device_xa, (d)->id, DPLL_REGISTERED))
#define ASSERT_DPLL_PIN_REGISTERED(p) \
	WARN_ON_ONCE(!xa_get_mark(&dpll_pin_xa, (p)->id, DPLL_REGISTERED))

struct dpll_device_registration {
	struct list_head list;
	const struct dpll_device_ops *ops;
	void *priv;
};

struct dpll_pin_registration {
	struct list_head list;
	const struct dpll_pin_ops *ops;
	void *priv;
};

struct dpll_device *dpll_device_get_by_id(int id)
{
	if (xa_get_mark(&dpll_device_xa, id, DPLL_REGISTERED))
		return xa_load(&dpll_device_xa, id);

	return NULL;
}

static struct dpll_pin_registration *
dpll_pin_registration_find(struct dpll_pin_ref *ref,
			   const struct dpll_pin_ops *ops, void *priv)
{
	struct dpll_pin_registration *reg;

	list_for_each_entry(reg, &ref->registration_list, list) {
		if (reg->ops == ops && reg->priv == priv)
			return reg;
	}
	return NULL;
}

static int
dpll_xa_ref_pin_add(struct xarray *xa_pins, struct dpll_pin *pin,
		    const struct dpll_pin_ops *ops, void *priv)
{
	struct dpll_pin_registration *reg;
	struct dpll_pin_ref *ref;
	bool ref_exists = false;
	unsigned long i;
	int ret;

	xa_for_each(xa_pins, i, ref) {
		if (ref->pin != pin)
			continue;
		reg = dpll_pin_registration_find(ref, ops, priv);
		if (reg) {
			refcount_inc(&ref->refcount);
			return 0;
		}
		ref_exists = true;
		break;
	}

	if (!ref_exists) {
		ref = kzalloc(sizeof(*ref), GFP_KERNEL);
		if (!ref)
			return -ENOMEM;
		ref->pin = pin;
		INIT_LIST_HEAD(&ref->registration_list);
		ret = xa_insert(xa_pins, pin->pin_idx, ref, GFP_KERNEL);
		if (ret) {
			kfree(ref);
			return ret;
		}
		refcount_set(&ref->refcount, 1);
	}

	reg = kzalloc(sizeof(*reg), GFP_KERNEL);
	if (!reg) {
		if (!ref_exists) {
			xa_erase(xa_pins, pin->pin_idx);
			kfree(ref);
		}
		return -ENOMEM;
	}
	reg->ops = ops;
	reg->priv = priv;
	if (ref_exists)
		refcount_inc(&ref->refcount);
	list_add_tail(&reg->list, &ref->registration_list);

	return 0;
}

static int dpll_xa_ref_pin_del(struct xarray *xa_pins, struct dpll_pin *pin,
			       const struct dpll_pin_ops *ops, void *priv)
{
	struct dpll_pin_registration *reg;
	struct dpll_pin_ref *ref;
	unsigned long i;

	xa_for_each(xa_pins, i, ref) {
		if (ref->pin != pin)
			continue;
		reg = dpll_pin_registration_find(ref, ops, priv);
		if (WARN_ON(!reg))
			return -EINVAL;
		list_del(&reg->list);
		kfree(reg);
		if (refcount_dec_and_test(&ref->refcount)) {
			xa_erase(xa_pins, i);
			WARN_ON(!list_empty(&ref->registration_list));
			kfree(ref);
		}
		return 0;
	}

	return -EINVAL;
}

static int
dpll_xa_ref_dpll_add(struct xarray *xa_dplls, struct dpll_device *dpll,
		     const struct dpll_pin_ops *ops, void *priv)
{
	struct dpll_pin_registration *reg;
	struct dpll_pin_ref *ref;
	bool ref_exists = false;
	unsigned long i;
	int ret;

	xa_for_each(xa_dplls, i, ref) {
		if (ref->dpll != dpll)
			continue;
		reg = dpll_pin_registration_find(ref, ops, priv);
		if (reg) {
			refcount_inc(&ref->refcount);
			return 0;
		}
		ref_exists = true;
		break;
	}

	if (!ref_exists) {
		ref = kzalloc(sizeof(*ref), GFP_KERNEL);
		if (!ref)
			return -ENOMEM;
		ref->dpll = dpll;
		INIT_LIST_HEAD(&ref->registration_list);
		ret = xa_insert(xa_dplls, dpll->id, ref, GFP_KERNEL);
		if (ret) {
			kfree(ref);
			return ret;
		}
		refcount_set(&ref->refcount, 1);
	}

	reg = kzalloc(sizeof(*reg), GFP_KERNEL);
	if (!reg) {
		if (!ref_exists) {
			xa_erase(xa_dplls, dpll->id);
			kfree(ref);
		}
		return -ENOMEM;
	}
	reg->ops = ops;
	reg->priv = priv;
	if (ref_exists)
		refcount_inc(&ref->refcount);
	list_add_tail(&reg->list, &ref->registration_list);

	return 0;
}

static void
dpll_xa_ref_dpll_del(struct xarray *xa_dplls, struct dpll_device *dpll,
		     const struct dpll_pin_ops *ops, void *priv)
{
	struct dpll_pin_registration *reg;
	struct dpll_pin_ref *ref;
	unsigned long i;

	xa_for_each(xa_dplls, i, ref) {
		if (ref->dpll != dpll)
			continue;
		reg = dpll_pin_registration_find(ref, ops, priv);
		if (WARN_ON(!reg))
			return;
		list_del(&reg->list);
		kfree(reg);
		if (refcount_dec_and_test(&ref->refcount)) {
			xa_erase(xa_dplls, i);
			WARN_ON(!list_empty(&ref->registration_list));
			kfree(ref);
		}
		return;
	}
}

struct dpll_pin_ref *dpll_xa_ref_dpll_first(struct xarray *xa_refs)
{
	struct dpll_pin_ref *ref;
	unsigned long i = 0;

	ref = xa_find(xa_refs, &i, ULONG_MAX, XA_PRESENT);
	WARN_ON(!ref);
	return ref;
}

static struct dpll_device *
dpll_device_alloc(const u64 clock_id, u32 device_idx, struct module *module)
{
	struct dpll_device *dpll;
	int ret;

	dpll = kzalloc(sizeof(*dpll), GFP_KERNEL);
	if (!dpll)
		return ERR_PTR(-ENOMEM);
	refcount_set(&dpll->refcount, 1);
	INIT_LIST_HEAD(&dpll->registration_list);
	dpll->device_idx = device_idx;
	dpll->clock_id = clock_id;
	dpll->module = module;
	ret = xa_alloc_cyclic(&dpll_device_xa, &dpll->id, dpll, xa_limit_32b,
			      &dpll_device_xa_id, GFP_KERNEL);
	if (ret < 0) {
		kfree(dpll);
		return ERR_PTR(ret);
	}
	xa_init_flags(&dpll->pin_refs, XA_FLAGS_ALLOC);

	return dpll;
}

/**
 * dpll_device_get - find existing or create new dpll device
 * @clock_id: clock_id of creator
 * @device_idx: idx given by device driver
 * @module: reference to registering module
 *
 * Get existing object of a dpll device, unique for given arguments.
 * Create new if doesn't exist yet.
 *
 * Context: Acquires a lock (dpll_lock)
 * Return:
 * * valid dpll_device struct pointer if succeeded
 * * ERR_PTR(X) - error
 */
struct dpll_device *
dpll_device_get(u64 clock_id, u32 device_idx, struct module *module)
{
	struct dpll_device *dpll, *ret = NULL;
	unsigned long index;

	mutex_lock(&dpll_lock);
	xa_for_each(&dpll_device_xa, index, dpll) {
		if (dpll->clock_id == clock_id &&
		    dpll->device_idx == device_idx &&
		    dpll->module == module) {
			ret = dpll;
			refcount_inc(&ret->refcount);
			break;
		}
	}
	if (!ret)
		ret = dpll_device_alloc(clock_id, device_idx, module);
	mutex_unlock(&dpll_lock);

	return ret;
}
EXPORT_SYMBOL_GPL(dpll_device_get);

/**
 * dpll_device_put - decrease the refcount and free memory if possible
 * @dpll: dpll_device struct pointer
 *
 * Context: Acquires a lock (dpll_lock)
 * Drop reference for a dpll device, if all references are gone, delete
 * dpll device object.
 */
void dpll_device_put(struct dpll_device *dpll)
{
	mutex_lock(&dpll_lock);
	if (refcount_dec_and_test(&dpll->refcount)) {
		ASSERT_DPLL_NOT_REGISTERED(dpll);
		WARN_ON_ONCE(!xa_empty(&dpll->pin_refs));
		xa_destroy(&dpll->pin_refs);
		xa_erase(&dpll_device_xa, dpll->id);
		WARN_ON(!list_empty(&dpll->registration_list));
		kfree(dpll);
	}
	mutex_unlock(&dpll_lock);
}
EXPORT_SYMBOL_GPL(dpll_device_put);

static struct dpll_device_registration *
dpll_device_registration_find(struct dpll_device *dpll,
			      const struct dpll_device_ops *ops, void *priv)
{
	struct dpll_device_registration *reg;

	list_for_each_entry(reg, &dpll->registration_list, list) {
		if (reg->ops == ops && reg->priv == priv)
			return reg;
	}
	return NULL;
}

/**
 * dpll_device_register - register the dpll device in the subsystem
 * @dpll: pointer to a dpll
 * @type: type of a dpll
 * @ops: ops for a dpll device
 * @priv: pointer to private information of owner
 *
 * Make dpll device available for user space.
 *
 * Context: Acquires a lock (dpll_lock)
 * Return:
 * * 0 on success
 * * negative - error value
 */
int dpll_device_register(struct dpll_device *dpll, enum dpll_type type,
			 const struct dpll_device_ops *ops, void *priv)
{
	struct dpll_device_registration *reg;
	bool first_registration = false;

	if (WARN_ON(!ops))
		return -EINVAL;
	if (WARN_ON(!ops->mode_get))
		return -EINVAL;
	if (WARN_ON(!ops->lock_status_get))
		return -EINVAL;
	if (WARN_ON(type < DPLL_TYPE_PPS || type > DPLL_TYPE_MAX))
		return -EINVAL;

	mutex_lock(&dpll_lock);
	reg = dpll_device_registration_find(dpll, ops, priv);
	if (reg) {
		mutex_unlock(&dpll_lock);
		return -EEXIST;
	}

	reg = kzalloc(sizeof(*reg), GFP_KERNEL);
	if (!reg) {
		mutex_unlock(&dpll_lock);
		return -ENOMEM;
	}
	reg->ops = ops;
	reg->priv = priv;
	dpll->type = type;
	first_registration = list_empty(&dpll->registration_list);
	list_add_tail(&reg->list, &dpll->registration_list);
	if (!first_registration) {
		mutex_unlock(&dpll_lock);
		return 0;
	}

	xa_set_mark(&dpll_device_xa, dpll->id, DPLL_REGISTERED);
	dpll_device_create_ntf(dpll);
	mutex_unlock(&dpll_lock);

	return 0;
}
EXPORT_SYMBOL_GPL(dpll_device_register);

/**
 * dpll_device_unregister - unregister dpll device
 * @dpll: registered dpll pointer
 * @ops: ops for a dpll device
 * @priv: pointer to private information of owner
 *
 * Unregister device, make it unavailable for userspace.
 * Note: It does not free the memory
 * Context: Acquires a lock (dpll_lock)
 */
void dpll_device_unregister(struct dpll_device *dpll,
			    const struct dpll_device_ops *ops, void *priv)
{
	struct dpll_device_registration *reg;

	mutex_lock(&dpll_lock);
	ASSERT_DPLL_REGISTERED(dpll);
	dpll_device_delete_ntf(dpll);
	reg = dpll_device_registration_find(dpll, ops, priv);
	if (WARN_ON(!reg)) {
		mutex_unlock(&dpll_lock);
		return;
	}
	list_del(&reg->list);
	kfree(reg);

	if (!list_empty(&dpll->registration_list)) {
		mutex_unlock(&dpll_lock);
		return;
	}
	xa_clear_mark(&dpll_device_xa, dpll->id, DPLL_REGISTERED);
	mutex_unlock(&dpll_lock);
}
EXPORT_SYMBOL_GPL(dpll_device_unregister);

static void dpll_pin_prop_free(struct dpll_pin_properties *prop)
{
	kfree(prop->package_label);
	kfree(prop->panel_label);
	kfree(prop->board_label);
	kfree(prop->freq_supported);
}

static int dpll_pin_prop_dup(const struct dpll_pin_properties *src,
			     struct dpll_pin_properties *dst)
{
	memcpy(dst, src, sizeof(*dst));
	if (src->freq_supported && src->freq_supported_num) {
		size_t freq_size = src->freq_supported_num *
				   sizeof(*src->freq_supported);
		dst->freq_supported = kmemdup(src->freq_supported,
					      freq_size, GFP_KERNEL);
		if (!src->freq_supported)
			return -ENOMEM;
	}
	if (src->board_label) {
		dst->board_label = kstrdup(src->board_label, GFP_KERNEL);
		if (!dst->board_label)
			goto err_board_label;
	}
	if (src->panel_label) {
		dst->panel_label = kstrdup(src->panel_label, GFP_KERNEL);
		if (!dst->panel_label)
			goto err_panel_label;
	}
	if (src->package_label) {
		dst->package_label = kstrdup(src->package_label, GFP_KERNEL);
		if (!dst->package_label)
			goto err_package_label;
	}

	return 0;

err_package_label:
	kfree(dst->panel_label);
err_panel_label:
	kfree(dst->board_label);
err_board_label:
	kfree(dst->freq_supported);
	return -ENOMEM;
}

static struct dpll_pin *
dpll_pin_alloc(u64 clock_id, u32 pin_idx, struct module *module,
	       const struct dpll_pin_properties *prop)
{
	struct dpll_pin *pin;
	int ret;

	pin = kzalloc(sizeof(*pin), GFP_KERNEL);
	if (!pin)
		return ERR_PTR(-ENOMEM);
	pin->pin_idx = pin_idx;
	pin->clock_id = clock_id;
	pin->module = module;
	if (WARN_ON(prop->type < DPLL_PIN_TYPE_MUX ||
		    prop->type > DPLL_PIN_TYPE_MAX)) {
		ret = -EINVAL;
		goto err_pin_prop;
	}
	ret = dpll_pin_prop_dup(prop, &pin->prop);
	if (ret)
		goto err_pin_prop;
	refcount_set(&pin->refcount, 1);
	xa_init_flags(&pin->dpll_refs, XA_FLAGS_ALLOC);
	xa_init_flags(&pin->parent_refs, XA_FLAGS_ALLOC);
	ret = xa_alloc_cyclic(&dpll_pin_xa, &pin->id, pin, xa_limit_32b,
			      &dpll_pin_xa_id, GFP_KERNEL);
	if (ret)
		goto err_xa_alloc;
	return pin;
err_xa_alloc:
	xa_destroy(&pin->dpll_refs);
	xa_destroy(&pin->parent_refs);
	dpll_pin_prop_free(&pin->prop);
err_pin_prop:
	kfree(pin);
	return ERR_PTR(ret);
}

static void dpll_netdev_pin_assign(struct net_device *dev, struct dpll_pin *dpll_pin)
{
	rtnl_lock();
	rcu_assign_pointer(dev->dpll_pin, dpll_pin);
	rtnl_unlock();
}

void dpll_netdev_pin_set(struct net_device *dev, struct dpll_pin *dpll_pin)
{
	WARN_ON(!dpll_pin);
	dpll_netdev_pin_assign(dev, dpll_pin);
}
EXPORT_SYMBOL(dpll_netdev_pin_set);

void dpll_netdev_pin_clear(struct net_device *dev)
{
	dpll_netdev_pin_assign(dev, NULL);
}
EXPORT_SYMBOL(dpll_netdev_pin_clear);

/**
 * dpll_pin_get - find existing or create new dpll pin
 * @clock_id: clock_id of creator
 * @pin_idx: idx given by dev driver
 * @module: reference to registering module
 * @prop: dpll pin properties
 *
 * Get existing object of a pin (unique for given arguments) or create new
 * if doesn't exist yet.
 *
 * Context: Acquires a lock (dpll_lock)
 * Return:
 * * valid allocated dpll_pin struct pointer if succeeded
 * * ERR_PTR(X) - error
 */
struct dpll_pin *
dpll_pin_get(u64 clock_id, u32 pin_idx, struct module *module,
	     const struct dpll_pin_properties *prop)
{
	struct dpll_pin *pos, *ret = NULL;
	unsigned long i;

	mutex_lock(&dpll_lock);
	xa_for_each(&dpll_pin_xa, i, pos) {
		if (pos->clock_id == clock_id &&
		    pos->pin_idx == pin_idx &&
		    pos->module == module) {
			ret = pos;
			refcount_inc(&ret->refcount);
			break;
		}
	}
	if (!ret)
		ret = dpll_pin_alloc(clock_id, pin_idx, module, prop);
	mutex_unlock(&dpll_lock);

	return ret;
}
EXPORT_SYMBOL_GPL(dpll_pin_get);

/**
 * dpll_pin_put - decrease the refcount and free memory if possible
 * @pin: pointer to a pin to be put
 *
 * Drop reference for a pin, if all references are gone, delete pin object.
 *
 * Context: Acquires a lock (dpll_lock)
 */
void dpll_pin_put(struct dpll_pin *pin)
{
	mutex_lock(&dpll_lock);
	if (refcount_dec_and_test(&pin->refcount)) {
		xa_erase(&dpll_pin_xa, pin->id);
		xa_destroy(&pin->dpll_refs);
		xa_destroy(&pin->parent_refs);
		dpll_pin_prop_free(&pin->prop);
		kfree_rcu(pin, rcu);
	}
	mutex_unlock(&dpll_lock);
}
EXPORT_SYMBOL_GPL(dpll_pin_put);

static int
__dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin,
		    const struct dpll_pin_ops *ops, void *priv)
{
	int ret;

	ret = dpll_xa_ref_pin_add(&dpll->pin_refs, pin, ops, priv);
	if (ret)
		return ret;
	ret = dpll_xa_ref_dpll_add(&pin->dpll_refs, dpll, ops, priv);
	if (ret)
		goto ref_pin_del;
	xa_set_mark(&dpll_pin_xa, pin->id, DPLL_REGISTERED);
	dpll_pin_create_ntf(pin);

	return ret;

ref_pin_del:
	dpll_xa_ref_pin_del(&dpll->pin_refs, pin, ops, priv);
	return ret;
}

/**
 * dpll_pin_register - register the dpll pin in the subsystem
 * @dpll: pointer to a dpll
 * @pin: pointer to a dpll pin
 * @ops: ops for a dpll pin ops
 * @priv: pointer to private information of owner
 *
 * Context: Acquires a lock (dpll_lock)
 * Return:
 * * 0 on success
 * * negative - error value
 */
int
dpll_pin_register(struct dpll_device *dpll, struct dpll_pin *pin,
		  const struct dpll_pin_ops *ops, void *priv)
{
	int ret;

	if (WARN_ON(!ops) ||
	    WARN_ON(!ops->state_on_dpll_get) ||
	    WARN_ON(!ops->direction_get))
		return -EINVAL;

	mutex_lock(&dpll_lock);
	if (WARN_ON(!(dpll->module == pin->module &&
		      dpll->clock_id == pin->clock_id)))
		ret = -EINVAL;
	else
		ret = __dpll_pin_register(dpll, pin, ops, priv);
	mutex_unlock(&dpll_lock);

	return ret;
}
EXPORT_SYMBOL_GPL(dpll_pin_register);

static void
__dpll_pin_unregister(struct dpll_device *dpll, struct dpll_pin *pin,
		      const struct dpll_pin_ops *ops, void *priv)
{
	ASSERT_DPLL_PIN_REGISTERED(pin);
	dpll_xa_ref_pin_del(&dpll->pin_refs, pin, ops, priv);
	dpll_xa_ref_dpll_del(&pin->dpll_refs, dpll, ops, priv);
	if (xa_empty(&pin->dpll_refs))
		xa_clear_mark(&dpll_pin_xa, pin->id, DPLL_REGISTERED);
}

/**
 * dpll_pin_unregister - unregister dpll pin from dpll device
 * @dpll: registered dpll pointer
 * @pin: pointer to a pin
 * @ops: ops for a dpll pin
 * @priv: pointer to private information of owner
 *
 * Note: It does not free the memory
 * Context: Acquires a lock (dpll_lock)
 */
void dpll_pin_unregister(struct dpll_device *dpll, struct dpll_pin *pin,
			 const struct dpll_pin_ops *ops, void *priv)
{
	if (WARN_ON(xa_empty(&dpll->pin_refs)))
		return;
	if (WARN_ON(!xa_empty(&pin->parent_refs)))
		return;

	mutex_lock(&dpll_lock);
	dpll_pin_delete_ntf(pin);
	__dpll_pin_unregister(dpll, pin, ops, priv);
	mutex_unlock(&dpll_lock);
}
EXPORT_SYMBOL_GPL(dpll_pin_unregister);

/**
 * dpll_pin_on_pin_register - register a pin with a parent pin
 * @parent: pointer to a parent pin
 * @pin: pointer to a pin
 * @ops: ops for a dpll pin
 * @priv: pointer to private information of owner
 *
 * Register a pin with a parent pin, create references between them and
 * between newly registered pin and dplls connected with a parent pin.
 *
 * Context: Acquires a lock (dpll_lock)
 * Return:
 * * 0 on success
 * * negative - error value
 */
int dpll_pin_on_pin_register(struct dpll_pin *parent, struct dpll_pin *pin,
			     const struct dpll_pin_ops *ops, void *priv)
{
	struct dpll_pin_ref *ref;
	unsigned long i, stop;
	int ret;

	if (WARN_ON(parent->prop.type != DPLL_PIN_TYPE_MUX))
		return -EINVAL;

	if (WARN_ON(!ops) ||
	    WARN_ON(!ops->state_on_pin_get) ||
	    WARN_ON(!ops->direction_get))
		return -EINVAL;

	mutex_lock(&dpll_lock);
	ret = dpll_xa_ref_pin_add(&pin->parent_refs, parent, ops, priv);
	if (ret)
		goto unlock;
	refcount_inc(&pin->refcount);
	xa_for_each(&parent->dpll_refs, i, ref) {
		ret = __dpll_pin_register(ref->dpll, pin, ops, priv);
		if (ret) {
			stop = i;
			goto dpll_unregister;
		}
		dpll_pin_create_ntf(pin);
	}
	mutex_unlock(&dpll_lock);

	return ret;

dpll_unregister:
	xa_for_each(&parent->dpll_refs, i, ref)
		if (i < stop) {
			__dpll_pin_unregister(ref->dpll, pin, ops, priv);
			dpll_pin_delete_ntf(pin);
		}
	refcount_dec(&pin->refcount);
	dpll_xa_ref_pin_del(&pin->parent_refs, parent, ops, priv);
unlock:
	mutex_unlock(&dpll_lock);
	return ret;
}
EXPORT_SYMBOL_GPL(dpll_pin_on_pin_register);

/**
 * dpll_pin_on_pin_unregister - unregister dpll pin from a parent pin
 * @parent: pointer to a parent pin
 * @pin: pointer to a pin
 * @ops: ops for a dpll pin
 * @priv: pointer to private information of owner
 *
 * Context: Acquires a lock (dpll_lock)
 * Note: It does not free the memory
 */
void dpll_pin_on_pin_unregister(struct dpll_pin *parent, struct dpll_pin *pin,
				const struct dpll_pin_ops *ops, void *priv)
{
	struct dpll_pin_ref *ref;
	unsigned long i;

	mutex_lock(&dpll_lock);
	dpll_pin_delete_ntf(pin);
	dpll_xa_ref_pin_del(&pin->parent_refs, parent, ops, priv);
	refcount_dec(&pin->refcount);
	xa_for_each(&pin->dpll_refs, i, ref)
		__dpll_pin_unregister(ref->dpll, pin, ops, priv);
	mutex_unlock(&dpll_lock);
}
EXPORT_SYMBOL_GPL(dpll_pin_on_pin_unregister);

static struct dpll_device_registration *
dpll_device_registration_first(struct dpll_device *dpll)
{
	struct dpll_device_registration *reg;

	reg = list_first_entry_or_null((struct list_head *)&dpll->registration_list,
				       struct dpll_device_registration, list);
	WARN_ON(!reg);
	return reg;
}

void *dpll_priv(struct dpll_device *dpll)
{
	struct dpll_device_registration *reg;

	reg = dpll_device_registration_first(dpll);
	return reg->priv;
}

const struct dpll_device_ops *dpll_device_ops(struct dpll_device *dpll)
{
	struct dpll_device_registration *reg;

	reg = dpll_device_registration_first(dpll);
	return reg->ops;
}

static struct dpll_pin_registration *
dpll_pin_registration_first(struct dpll_pin_ref *ref)
{
	struct dpll_pin_registration *reg;

	reg = list_first_entry_or_null(&ref->registration_list,
				       struct dpll_pin_registration, list);
	WARN_ON(!reg);
	return reg;
}

void *dpll_pin_on_dpll_priv(struct dpll_device *dpll,
			    struct dpll_pin *pin)
{
	struct dpll_pin_registration *reg;
	struct dpll_pin_ref *ref;

	ref = xa_load(&dpll->pin_refs, pin->pin_idx);
	if (!ref)
		return NULL;
	reg = dpll_pin_registration_first(ref);
	return reg->priv;
}

void *dpll_pin_on_pin_priv(struct dpll_pin *parent,
			   struct dpll_pin *pin)
{
	struct dpll_pin_registration *reg;
	struct dpll_pin_ref *ref;

	ref = xa_load(&pin->parent_refs, parent->pin_idx);
	if (!ref)
		return NULL;
	reg = dpll_pin_registration_first(ref);
	return reg->priv;
}

const struct dpll_pin_ops *dpll_pin_ops(struct dpll_pin_ref *ref)
{
	struct dpll_pin_registration *reg;

	reg = dpll_pin_registration_first(ref);
	return reg->ops;
}

static int __init dpll_init(void)
{
	int ret;

	ret = genl_register_family(&dpll_nl_family);
	if (ret)
		goto error;

	return 0;

error:
	mutex_destroy(&dpll_lock);
	return ret;
}

static void __exit dpll_exit(void)
{
	genl_unregister_family(&dpll_nl_family);
	mutex_destroy(&dpll_lock);
}

subsys_initcall(dpll_init);
module_exit(dpll_exit);
