// SPDX-License-Identifier: GPL-2.0-only
//
// Framework for Ethernet Power Sourcing Equipment
//
// Copyright (c) 2022 Pengutronix, Oleksij Rempel <kernel@pengutronix.de>
//

#include <linux/device.h>
#include <linux/of.h>
#include <linux/pse-pd/pse.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>

static DEFINE_MUTEX(pse_list_mutex);
static LIST_HEAD(pse_controller_list);

/**
 * struct pse_control - a PSE control
 * @pcdev: a pointer to the PSE controller device
 *         this PSE control belongs to
 * @ps: PSE PI supply of the PSE control
 * @list: list entry for the pcdev's PSE controller list
 * @id: ID of the PSE line in the PSE controller device
 * @refcnt: Number of gets of this pse_control
 */
struct pse_control {
	struct pse_controller_dev *pcdev;
	struct regulator *ps;
	struct list_head list;
	unsigned int id;
	struct kref refcnt;
};

static int of_load_single_pse_pi_pairset(struct device_node *node,
					 struct pse_pi *pi,
					 int pairset_num)
{
	struct device_node *pairset_np;
	const char *name;
	int ret;

	ret = of_property_read_string_index(node, "pairset-names",
					    pairset_num, &name);
	if (ret)
		return ret;

	if (!strcmp(name, "alternative-a")) {
		pi->pairset[pairset_num].pinout = ALTERNATIVE_A;
	} else if (!strcmp(name, "alternative-b")) {
		pi->pairset[pairset_num].pinout = ALTERNATIVE_B;
	} else {
		pr_err("pse: wrong pairset-names value %s (%pOF)\n",
		       name, node);
		return -EINVAL;
	}

	pairset_np = of_parse_phandle(node, "pairsets", pairset_num);
	if (!pairset_np)
		return -ENODEV;

	pi->pairset[pairset_num].np = pairset_np;

	return 0;
}

/**
 * of_load_pse_pi_pairsets - load PSE PI pairsets pinout and polarity
 * @node: a pointer of the device node
 * @pi: a pointer of the PSE PI to fill
 * @npairsets: the number of pairsets (1 or 2) used by the PI
 *
 * Return: 0 on success and failure value on error
 */
static int of_load_pse_pi_pairsets(struct device_node *node,
				   struct pse_pi *pi,
				   int npairsets)
{
	int i, ret;

	ret = of_property_count_strings(node, "pairset-names");
	if (ret != npairsets) {
		pr_err("pse: amount of pairsets and pairset-names is not equal %d != %d (%pOF)\n",
		       npairsets, ret, node);
		return -EINVAL;
	}

	for (i = 0; i < npairsets; i++) {
		ret = of_load_single_pse_pi_pairset(node, pi, i);
		if (ret)
			goto out;
	}

	if (npairsets == 2 &&
	    pi->pairset[0].pinout == pi->pairset[1].pinout) {
		pr_err("pse: two PI pairsets can not have identical pinout (%pOF)",
		       node);
		ret = -EINVAL;
	}

out:
	/* If an error appears, release all the pairset device node kref */
	if (ret) {
		of_node_put(pi->pairset[0].np);
		pi->pairset[0].np = NULL;
		of_node_put(pi->pairset[1].np);
		pi->pairset[1].np = NULL;
	}

	return ret;
}

static void pse_release_pis(struct pse_controller_dev *pcdev)
{
	int i;

	for (i = 0; i <= pcdev->nr_lines; i++) {
		of_node_put(pcdev->pi[i].pairset[0].np);
		of_node_put(pcdev->pi[i].pairset[1].np);
		of_node_put(pcdev->pi[i].np);
	}
	kfree(pcdev->pi);
}

/**
 * of_load_pse_pis - load all the PSE PIs
 * @pcdev: a pointer to the PSE controller device
 *
 * Return: 0 on success and failure value on error
 */
static int of_load_pse_pis(struct pse_controller_dev *pcdev)
{
	struct device_node *np = pcdev->dev->of_node;
	struct device_node *node, *pis;
	int ret;

	if (!np)
		return -ENODEV;

	pcdev->pi = kcalloc(pcdev->nr_lines, sizeof(*pcdev->pi), GFP_KERNEL);
	if (!pcdev->pi)
		return -ENOMEM;

	pis = of_get_child_by_name(np, "pse-pis");
	if (!pis) {
		/* no description of PSE PIs */
		pcdev->no_of_pse_pi = true;
		return 0;
	}

	for_each_child_of_node(pis, node) {
		struct pse_pi pi = {0};
		u32 id;

		if (!of_node_name_eq(node, "pse-pi"))
			continue;

		ret = of_property_read_u32(node, "reg", &id);
		if (ret) {
			dev_err(pcdev->dev,
				"can't get reg property for node '%pOF'",
				node);
			goto out;
		}

		if (id >= pcdev->nr_lines) {
			dev_err(pcdev->dev,
				"reg value (%u) is out of range (%u) (%pOF)\n",
				id, pcdev->nr_lines, node);
			ret = -EINVAL;
			goto out;
		}

		if (pcdev->pi[id].np) {
			dev_err(pcdev->dev,
				"other node with same reg value was already registered. %pOF : %pOF\n",
				pcdev->pi[id].np, node);
			ret = -EINVAL;
			goto out;
		}

		ret = of_count_phandle_with_args(node, "pairsets", NULL);
		/* npairsets is limited to value one or two */
		if (ret == 1 || ret == 2) {
			ret = of_load_pse_pi_pairsets(node, &pi, ret);
			if (ret)
				goto out;
		} else if (ret != ENOENT) {
			dev_err(pcdev->dev,
				"error: wrong number of pairsets. Should be 1 or 2, got %d (%pOF)\n",
				ret, node);
			ret = -EINVAL;
			goto out;
		}

		of_node_get(node);
		pi.np = node;
		memcpy(&pcdev->pi[id], &pi, sizeof(pi));
	}

	of_node_put(pis);
	return 0;

out:
	pse_release_pis(pcdev);
	of_node_put(node);
	of_node_put(pis);
	return ret;
}

static int pse_pi_is_enabled(struct regulator_dev *rdev)
{
	struct pse_controller_dev *pcdev = rdev_get_drvdata(rdev);
	const struct pse_controller_ops *ops;
	int id, ret;

	ops = pcdev->ops;
	if (!ops->pi_is_enabled)
		return -EOPNOTSUPP;

	id = rdev_get_id(rdev);
	mutex_lock(&pcdev->lock);
	ret = ops->pi_is_enabled(pcdev, id);
	mutex_unlock(&pcdev->lock);

	return ret;
}

static int pse_pi_enable(struct regulator_dev *rdev)
{
	struct pse_controller_dev *pcdev = rdev_get_drvdata(rdev);
	const struct pse_controller_ops *ops;
	int id, ret;

	ops = pcdev->ops;
	if (!ops->pi_enable)
		return -EOPNOTSUPP;

	id = rdev_get_id(rdev);
	mutex_lock(&pcdev->lock);
	ret = ops->pi_enable(pcdev, id);
	if (!ret)
		pcdev->pi[id].admin_state_enabled = 1;
	mutex_unlock(&pcdev->lock);

	return ret;
}

static int pse_pi_disable(struct regulator_dev *rdev)
{
	struct pse_controller_dev *pcdev = rdev_get_drvdata(rdev);
	const struct pse_controller_ops *ops;
	int id, ret;

	ops = pcdev->ops;
	if (!ops->pi_disable)
		return -EOPNOTSUPP;

	id = rdev_get_id(rdev);
	mutex_lock(&pcdev->lock);
	ret = ops->pi_disable(pcdev, id);
	if (!ret)
		pcdev->pi[id].admin_state_enabled = 0;
	mutex_unlock(&pcdev->lock);

	return ret;
}

static int _pse_pi_get_voltage(struct regulator_dev *rdev)
{
	struct pse_controller_dev *pcdev = rdev_get_drvdata(rdev);
	const struct pse_controller_ops *ops;
	int id;

	ops = pcdev->ops;
	if (!ops->pi_get_voltage)
		return -EOPNOTSUPP;

	id = rdev_get_id(rdev);
	return ops->pi_get_voltage(pcdev, id);
}

static int pse_pi_get_voltage(struct regulator_dev *rdev)
{
	struct pse_controller_dev *pcdev = rdev_get_drvdata(rdev);
	int ret;

	mutex_lock(&pcdev->lock);
	ret = _pse_pi_get_voltage(rdev);
	mutex_unlock(&pcdev->lock);

	return ret;
}

static int _pse_ethtool_get_status(struct pse_controller_dev *pcdev,
				   int id,
				   struct netlink_ext_ack *extack,
				   struct pse_control_status *status);

static int pse_pi_get_current_limit(struct regulator_dev *rdev)
{
	struct pse_controller_dev *pcdev = rdev_get_drvdata(rdev);
	const struct pse_controller_ops *ops;
	struct netlink_ext_ack extack = {};
	struct pse_control_status st = {};
	int id, uV, ret;
	s64 tmp_64;

	ops = pcdev->ops;
	id = rdev_get_id(rdev);
	mutex_lock(&pcdev->lock);
	if (ops->pi_get_current_limit) {
		ret = ops->pi_get_current_limit(pcdev, id);
		goto out;
	}

	/* If pi_get_current_limit() callback not populated get voltage
	 * from pi_get_voltage() and power limit from ethtool_get_status()
	 *  to calculate current limit.
	 */
	ret = _pse_pi_get_voltage(rdev);
	if (!ret) {
		dev_err(pcdev->dev, "Voltage null\n");
		ret = -ERANGE;
		goto out;
	}
	if (ret < 0)
		goto out;
	uV = ret;

	ret = _pse_ethtool_get_status(pcdev, id, &extack, &st);
	if (ret)
		goto out;

	if (!st.c33_avail_pw_limit) {
		ret = -ENODATA;
		goto out;
	}

	tmp_64 = st.c33_avail_pw_limit;
	tmp_64 *= 1000000000ull;
	/* uA = mW * 1000000000 / uV */
	ret = DIV_ROUND_CLOSEST_ULL(tmp_64, uV);

out:
	mutex_unlock(&pcdev->lock);
	return ret;
}

static int pse_pi_set_current_limit(struct regulator_dev *rdev, int min_uA,
				    int max_uA)
{
	struct pse_controller_dev *pcdev = rdev_get_drvdata(rdev);
	const struct pse_controller_ops *ops;
	int id, ret;

	ops = pcdev->ops;
	if (!ops->pi_set_current_limit)
		return -EOPNOTSUPP;

	id = rdev_get_id(rdev);
	mutex_lock(&pcdev->lock);
	ret = ops->pi_set_current_limit(pcdev, id, max_uA);
	mutex_unlock(&pcdev->lock);

	return ret;
}

static const struct regulator_ops pse_pi_ops = {
	.is_enabled = pse_pi_is_enabled,
	.enable = pse_pi_enable,
	.disable = pse_pi_disable,
	.get_voltage = pse_pi_get_voltage,
	.get_current_limit = pse_pi_get_current_limit,
	.set_current_limit = pse_pi_set_current_limit,
};

static int
devm_pse_pi_regulator_register(struct pse_controller_dev *pcdev,
			       char *name, int id)
{
	struct regulator_init_data *rinit_data;
	struct regulator_config rconfig = {0};
	struct regulator_desc *rdesc;
	struct regulator_dev *rdev;

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

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

	/* Regulator descriptor id have to be the same as its associated
	 * PSE PI id for the well functioning of the PSE controls.
	 */
	rdesc->id = id;
	rdesc->name = name;
	rdesc->type = REGULATOR_VOLTAGE;
	rdesc->ops = &pse_pi_ops;
	rdesc->owner = pcdev->owner;

	rinit_data->constraints.valid_ops_mask = REGULATOR_CHANGE_STATUS;

	if (pcdev->ops->pi_set_current_limit) {
		rinit_data->constraints.valid_ops_mask |=
			REGULATOR_CHANGE_CURRENT;
		rinit_data->constraints.max_uA = MAX_PI_CURRENT;
	}

	rinit_data->supply_regulator = "vpwr";

	rconfig.dev = pcdev->dev;
	rconfig.driver_data = pcdev;
	rconfig.init_data = rinit_data;

	rdev = devm_regulator_register(pcdev->dev, rdesc, &rconfig);
	if (IS_ERR(rdev)) {
		dev_err_probe(pcdev->dev, PTR_ERR(rdev),
			      "Failed to register regulator\n");
		return PTR_ERR(rdev);
	}

	pcdev->pi[id].rdev = rdev;

	return 0;
}

/**
 * pse_controller_register - register a PSE controller device
 * @pcdev: a pointer to the initialized PSE controller device
 *
 * Return: 0 on success and failure value on error
 */
int pse_controller_register(struct pse_controller_dev *pcdev)
{
	size_t reg_name_len;
	int ret, i;

	mutex_init(&pcdev->lock);
	INIT_LIST_HEAD(&pcdev->pse_control_head);

	if (!pcdev->nr_lines)
		pcdev->nr_lines = 1;

	ret = of_load_pse_pis(pcdev);
	if (ret)
		return ret;

	if (pcdev->ops->setup_pi_matrix) {
		ret = pcdev->ops->setup_pi_matrix(pcdev);
		if (ret)
			return ret;
	}

	/* Each regulator name len is pcdev dev name + 7 char +
	 * int max digit number (10) + 1
	 */
	reg_name_len = strlen(dev_name(pcdev->dev)) + 18;

	/* Register PI regulators */
	for (i = 0; i < pcdev->nr_lines; i++) {
		char *reg_name;

		/* Do not register regulator for PIs not described */
		if (!pcdev->no_of_pse_pi && !pcdev->pi[i].np)
			continue;

		reg_name = devm_kzalloc(pcdev->dev, reg_name_len, GFP_KERNEL);
		if (!reg_name)
			return -ENOMEM;

		snprintf(reg_name, reg_name_len, "pse-%s_pi%d",
			 dev_name(pcdev->dev), i);

		ret = devm_pse_pi_regulator_register(pcdev, reg_name, i);
		if (ret)
			return ret;
	}

	mutex_lock(&pse_list_mutex);
	list_add(&pcdev->list, &pse_controller_list);
	mutex_unlock(&pse_list_mutex);

	return 0;
}
EXPORT_SYMBOL_GPL(pse_controller_register);

/**
 * pse_controller_unregister - unregister a PSE controller device
 * @pcdev: a pointer to the PSE controller device
 */
void pse_controller_unregister(struct pse_controller_dev *pcdev)
{
	pse_release_pis(pcdev);
	mutex_lock(&pse_list_mutex);
	list_del(&pcdev->list);
	mutex_unlock(&pse_list_mutex);
}
EXPORT_SYMBOL_GPL(pse_controller_unregister);

static void devm_pse_controller_release(struct device *dev, void *res)
{
	pse_controller_unregister(*(struct pse_controller_dev **)res);
}

/**
 * devm_pse_controller_register - resource managed pse_controller_register()
 * @dev: device that is registering this PSE controller
 * @pcdev: a pointer to the initialized PSE controller device
 *
 * Managed pse_controller_register(). For PSE controllers registered by
 * this function, pse_controller_unregister() is automatically called on
 * driver detach. See pse_controller_register() for more information.
 *
 * Return: 0 on success and failure value on error
 */
int devm_pse_controller_register(struct device *dev,
				 struct pse_controller_dev *pcdev)
{
	struct pse_controller_dev **pcdevp;
	int ret;

	pcdevp = devres_alloc(devm_pse_controller_release, sizeof(*pcdevp),
			      GFP_KERNEL);
	if (!pcdevp)
		return -ENOMEM;

	ret = pse_controller_register(pcdev);
	if (ret) {
		devres_free(pcdevp);
		return ret;
	}

	*pcdevp = pcdev;
	devres_add(dev, pcdevp);

	return 0;
}
EXPORT_SYMBOL_GPL(devm_pse_controller_register);

/* PSE control section */

static void __pse_control_release(struct kref *kref)
{
	struct pse_control *psec = container_of(kref, struct pse_control,
						  refcnt);

	lockdep_assert_held(&pse_list_mutex);

	if (psec->pcdev->pi[psec->id].admin_state_enabled)
		regulator_disable(psec->ps);
	devm_regulator_put(psec->ps);

	module_put(psec->pcdev->owner);

	list_del(&psec->list);
	kfree(psec);
}

static void __pse_control_put_internal(struct pse_control *psec)
{
	lockdep_assert_held(&pse_list_mutex);

	kref_put(&psec->refcnt, __pse_control_release);
}

/**
 * pse_control_put - free the PSE control
 * @psec: PSE control pointer
 */
void pse_control_put(struct pse_control *psec)
{
	if (IS_ERR_OR_NULL(psec))
		return;

	mutex_lock(&pse_list_mutex);
	__pse_control_put_internal(psec);
	mutex_unlock(&pse_list_mutex);
}
EXPORT_SYMBOL_GPL(pse_control_put);

static struct pse_control *
pse_control_get_internal(struct pse_controller_dev *pcdev, unsigned int index)
{
	struct pse_control *psec;
	int ret;

	lockdep_assert_held(&pse_list_mutex);

	list_for_each_entry(psec, &pcdev->pse_control_head, list) {
		if (psec->id == index) {
			kref_get(&psec->refcnt);
			return psec;
		}
	}

	psec = kzalloc(sizeof(*psec), GFP_KERNEL);
	if (!psec)
		return ERR_PTR(-ENOMEM);

	if (!try_module_get(pcdev->owner)) {
		ret = -ENODEV;
		goto free_psec;
	}

	psec->ps = devm_regulator_get_exclusive(pcdev->dev,
						rdev_get_name(pcdev->pi[index].rdev));
	if (IS_ERR(psec->ps)) {
		ret = PTR_ERR(psec->ps);
		goto put_module;
	}

	ret = regulator_is_enabled(psec->ps);
	if (ret < 0)
		goto regulator_put;

	pcdev->pi[index].admin_state_enabled = ret;

	psec->pcdev = pcdev;
	list_add(&psec->list, &pcdev->pse_control_head);
	psec->id = index;
	kref_init(&psec->refcnt);

	return psec;

regulator_put:
	devm_regulator_put(psec->ps);
put_module:
	module_put(pcdev->owner);
free_psec:
	kfree(psec);

	return ERR_PTR(ret);
}

/**
 * of_pse_match_pi - Find the PSE PI id matching the device node phandle
 * @pcdev: a pointer to the PSE controller device
 * @np: a pointer to the device node
 *
 * Return: id of the PSE PI, -EINVAL if not found
 */
static int of_pse_match_pi(struct pse_controller_dev *pcdev,
			   struct device_node *np)
{
	int i;

	for (i = 0; i <= pcdev->nr_lines; i++) {
		if (pcdev->pi[i].np == np)
			return i;
	}

	return -EINVAL;
}

/**
 * psec_id_xlate - translate pse_spec to the PSE line number according
 *		   to the number of pse-cells in case of no pse_pi node
 * @pcdev: a pointer to the PSE controller device
 * @pse_spec: PSE line specifier as found in the device tree
 *
 * Return: 0 if #pse-cells = <0>. Return PSE line number otherwise.
 */
static int psec_id_xlate(struct pse_controller_dev *pcdev,
			 const struct of_phandle_args *pse_spec)
{
	if (!pcdev->of_pse_n_cells)
		return 0;

	if (pcdev->of_pse_n_cells > 1 ||
	    pse_spec->args[0] >= pcdev->nr_lines)
		return -EINVAL;

	return pse_spec->args[0];
}

struct pse_control *of_pse_control_get(struct device_node *node)
{
	struct pse_controller_dev *r, *pcdev;
	struct of_phandle_args args;
	struct pse_control *psec;
	int psec_id;
	int ret;

	if (!node)
		return ERR_PTR(-EINVAL);

	ret = of_parse_phandle_with_args(node, "pses", "#pse-cells", 0, &args);
	if (ret)
		return ERR_PTR(ret);

	mutex_lock(&pse_list_mutex);
	pcdev = NULL;
	list_for_each_entry(r, &pse_controller_list, list) {
		if (!r->no_of_pse_pi) {
			ret = of_pse_match_pi(r, args.np);
			if (ret >= 0) {
				pcdev = r;
				psec_id = ret;
				break;
			}
		} else if (args.np == r->dev->of_node) {
			pcdev = r;
			break;
		}
	}

	if (!pcdev) {
		psec = ERR_PTR(-EPROBE_DEFER);
		goto out;
	}

	if (WARN_ON(args.args_count != pcdev->of_pse_n_cells)) {
		psec = ERR_PTR(-EINVAL);
		goto out;
	}

	if (pcdev->no_of_pse_pi) {
		psec_id = psec_id_xlate(pcdev, &args);
		if (psec_id < 0) {
			psec = ERR_PTR(psec_id);
			goto out;
		}
	}

	/* pse_list_mutex also protects the pcdev's pse_control list */
	psec = pse_control_get_internal(pcdev, psec_id);

out:
	mutex_unlock(&pse_list_mutex);
	of_node_put(args.np);

	return psec;
}
EXPORT_SYMBOL_GPL(of_pse_control_get);

static int _pse_ethtool_get_status(struct pse_controller_dev *pcdev,
				   int id,
				   struct netlink_ext_ack *extack,
				   struct pse_control_status *status)
{
	const struct pse_controller_ops *ops;

	ops = pcdev->ops;
	if (!ops->ethtool_get_status) {
		NL_SET_ERR_MSG(extack,
			       "PSE driver does not support status report");
		return -EOPNOTSUPP;
	}

	return ops->ethtool_get_status(pcdev, id, extack, status);
}

/**
 * pse_ethtool_get_status - get status of PSE control
 * @psec: PSE control pointer
 * @extack: extack for reporting useful error messages
 * @status: struct to store PSE status
 *
 * Return: 0 on success and failure value on error
 */
int pse_ethtool_get_status(struct pse_control *psec,
			   struct netlink_ext_ack *extack,
			   struct pse_control_status *status)
{
	int err;

	mutex_lock(&psec->pcdev->lock);
	err = _pse_ethtool_get_status(psec->pcdev, psec->id, extack, status);
	mutex_unlock(&psec->pcdev->lock);

	return err;
}
EXPORT_SYMBOL_GPL(pse_ethtool_get_status);

static int pse_ethtool_c33_set_config(struct pse_control *psec,
				      const struct pse_control_config *config)
{
	int err = 0;

	/* Look at admin_state_enabled status to not call regulator_enable
	 * or regulator_disable twice creating a regulator counter mismatch
	 */
	switch (config->c33_admin_control) {
	case ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED:
		if (!psec->pcdev->pi[psec->id].admin_state_enabled)
			err = regulator_enable(psec->ps);
		break;
	case ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED:
		if (psec->pcdev->pi[psec->id].admin_state_enabled)
			err = regulator_disable(psec->ps);
		break;
	default:
		err = -EOPNOTSUPP;
	}

	return err;
}

static int pse_ethtool_podl_set_config(struct pse_control *psec,
				       const struct pse_control_config *config)
{
	int err = 0;

	/* Look at admin_state_enabled status to not call regulator_enable
	 * or regulator_disable twice creating a regulator counter mismatch
	 */
	switch (config->podl_admin_control) {
	case ETHTOOL_PODL_PSE_ADMIN_STATE_ENABLED:
		if (!psec->pcdev->pi[psec->id].admin_state_enabled)
			err = regulator_enable(psec->ps);
		break;
	case ETHTOOL_PODL_PSE_ADMIN_STATE_DISABLED:
		if (psec->pcdev->pi[psec->id].admin_state_enabled)
			err = regulator_disable(psec->ps);
		break;
	default:
		err = -EOPNOTSUPP;
	}

	return err;
}

/**
 * pse_ethtool_set_config - set PSE control configuration
 * @psec: PSE control pointer
 * @extack: extack for reporting useful error messages
 * @config: Configuration of the test to run
 *
 * Return: 0 on success and failure value on error
 */
int pse_ethtool_set_config(struct pse_control *psec,
			   struct netlink_ext_ack *extack,
			   const struct pse_control_config *config)
{
	int err = 0;

	if (pse_has_c33(psec) && config->c33_admin_control) {
		err = pse_ethtool_c33_set_config(psec, config);
		if (err)
			return err;
	}

	if (pse_has_podl(psec) && config->podl_admin_control)
		err = pse_ethtool_podl_set_config(psec, config);

	return err;
}
EXPORT_SYMBOL_GPL(pse_ethtool_set_config);

/**
 * pse_ethtool_set_pw_limit - set PSE control power limit
 * @psec: PSE control pointer
 * @extack: extack for reporting useful error messages
 * @pw_limit: power limit value in mW
 *
 * Return: 0 on success and failure value on error
 */
int pse_ethtool_set_pw_limit(struct pse_control *psec,
			     struct netlink_ext_ack *extack,
			     const unsigned int pw_limit)
{
	int uV, uA, ret;
	s64 tmp_64;

	ret = regulator_get_voltage(psec->ps);
	if (!ret) {
		NL_SET_ERR_MSG(extack,
			       "Can't calculate the current, PSE voltage read is 0");
		return -ERANGE;
	}
	if (ret < 0) {
		NL_SET_ERR_MSG(extack,
			       "Error reading PSE voltage");
		return ret;
	}
	uV = ret;

	tmp_64 = pw_limit;
	tmp_64 *= 1000000000ull;
	/* uA = mW * 1000000000 / uV */
	uA = DIV_ROUND_CLOSEST_ULL(tmp_64, uV);

	return regulator_set_current_limit(psec->ps, 0, uA);
}
EXPORT_SYMBOL_GPL(pse_ethtool_set_pw_limit);

bool pse_has_podl(struct pse_control *psec)
{
	return psec->pcdev->types & ETHTOOL_PSE_PODL;
}
EXPORT_SYMBOL_GPL(pse_has_podl);

bool pse_has_c33(struct pse_control *psec)
{
	return psec->pcdev->types & ETHTOOL_PSE_C33;
}
EXPORT_SYMBOL_GPL(pse_has_c33);
