// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2016, NVIDIA CORPORATION.
 */

#include <common.h>
#include <dm.h>
#include <fdtdec.h>
#include <log.h>
#include <malloc.h>
#include <reset.h>
#include <reset-uclass.h>
#include <dm/devres.h>
#include <dm/lists.h>

static inline struct reset_ops *reset_dev_ops(struct udevice *dev)
{
	return (struct reset_ops *)dev->driver->ops;
}

static int reset_of_xlate_default(struct reset_ctl *reset_ctl,
				  struct ofnode_phandle_args *args)
{
	debug("%s(reset_ctl=%p)\n", __func__, reset_ctl);

	if (args->args_count != 1) {
		debug("Invaild args_count: %d\n", args->args_count);
		return -EINVAL;
	}

	reset_ctl->id = args->args[0];

	return 0;
}

static int reset_get_by_index_tail(int ret, ofnode node,
				   struct ofnode_phandle_args *args,
				   const char *list_name, int index,
				   struct reset_ctl *reset_ctl)
{
	struct udevice *dev_reset;
	struct reset_ops *ops;

	assert(reset_ctl);
	reset_ctl->dev = NULL;
	if (ret)
		return ret;

	ret = uclass_get_device_by_ofnode(UCLASS_RESET, args->node,
					  &dev_reset);
	if (ret) {
		debug("%s: uclass_get_device_by_ofnode() failed: %d\n",
		      __func__, ret);
		debug("%s %d\n", ofnode_get_name(args->node), args->args[0]);
		return ret;
	}
	ops = reset_dev_ops(dev_reset);

	reset_ctl->dev = dev_reset;
	if (ops->of_xlate)
		ret = ops->of_xlate(reset_ctl, args);
	else
		ret = reset_of_xlate_default(reset_ctl, args);
	if (ret) {
		debug("of_xlate() failed: %d\n", ret);
		return ret;
	}

	ret = ops->request(reset_ctl);
	if (ret) {
		debug("ops->request() failed: %d\n", ret);
		return ret;
	}

	return 0;
}

int reset_get_by_index(struct udevice *dev, int index,
		       struct reset_ctl *reset_ctl)
{
	struct ofnode_phandle_args args;
	int ret;

	ret = dev_read_phandle_with_args(dev, "resets", "#reset-cells", 0,
					 index, &args);

	return reset_get_by_index_tail(ret, dev_ofnode(dev), &args, "resets",
				       index > 0, reset_ctl);
}

int reset_get_by_index_nodev(ofnode node, int index,
			     struct reset_ctl *reset_ctl)
{
	struct ofnode_phandle_args args;
	int ret;

	ret = ofnode_parse_phandle_with_args(node, "resets", "#reset-cells", 0,
					     index, &args);

	return reset_get_by_index_tail(ret, node, &args, "resets",
				       index > 0, reset_ctl);
}

static int __reset_get_bulk(struct udevice *dev, ofnode node,
			    struct reset_ctl_bulk *bulk)
{
	int i, ret, err, count;

	bulk->count = 0;

	count = ofnode_count_phandle_with_args(node, "resets", "#reset-cells",
					       0);
	if (count < 1)
		return count;

	bulk->resets = devm_kcalloc(dev, count, sizeof(struct reset_ctl),
				    GFP_KERNEL);
	if (!bulk->resets)
		return -ENOMEM;

	for (i = 0; i < count; i++) {
		ret = reset_get_by_index_nodev(node, i, &bulk->resets[i]);
		if (ret < 0)
			goto bulk_get_err;

		++bulk->count;
	}

	return 0;

bulk_get_err:
	err = reset_release_all(bulk->resets, bulk->count);
	if (err)
		debug("%s: could release all resets for %p\n",
		      __func__, dev);

	return ret;
}

int reset_get_bulk(struct udevice *dev, struct reset_ctl_bulk *bulk)
{
	return __reset_get_bulk(dev, dev_ofnode(dev), bulk);
}

int reset_get_by_name(struct udevice *dev, const char *name,
		     struct reset_ctl *reset_ctl)
{
	int index;

	debug("%s(dev=%p, name=%s, reset_ctl=%p)\n", __func__, dev, name,
	      reset_ctl);
	reset_ctl->dev = NULL;

	index = dev_read_stringlist_search(dev, "reset-names", name);
	if (index < 0) {
		debug("fdt_stringlist_search() failed: %d\n", index);
		return index;
	}

	return reset_get_by_index(dev, index, reset_ctl);
}

int reset_request(struct reset_ctl *reset_ctl)
{
	struct reset_ops *ops = reset_dev_ops(reset_ctl->dev);

	debug("%s(reset_ctl=%p)\n", __func__, reset_ctl);

	return ops->request(reset_ctl);
}

int reset_free(struct reset_ctl *reset_ctl)
{
	struct reset_ops *ops = reset_dev_ops(reset_ctl->dev);

	debug("%s(reset_ctl=%p)\n", __func__, reset_ctl);

	return ops->rfree(reset_ctl);
}

int reset_assert(struct reset_ctl *reset_ctl)
{
	struct reset_ops *ops = reset_dev_ops(reset_ctl->dev);

	debug("%s(reset_ctl=%p)\n", __func__, reset_ctl);

	return ops->rst_assert(reset_ctl);
}

int reset_assert_bulk(struct reset_ctl_bulk *bulk)
{
	int i, ret;

	for (i = 0; i < bulk->count; i++) {
		ret = reset_assert(&bulk->resets[i]);
		if (ret < 0)
			return ret;
	}

	return 0;
}

int reset_deassert(struct reset_ctl *reset_ctl)
{
	struct reset_ops *ops = reset_dev_ops(reset_ctl->dev);

	debug("%s(reset_ctl=%p)\n", __func__, reset_ctl);

	return ops->rst_deassert(reset_ctl);
}

int reset_deassert_bulk(struct reset_ctl_bulk *bulk)
{
	int i, ret;

	for (i = 0; i < bulk->count; i++) {
		ret = reset_deassert(&bulk->resets[i]);
		if (ret < 0)
			return ret;
	}

	return 0;
}

int reset_status(struct reset_ctl *reset_ctl)
{
	struct reset_ops *ops = reset_dev_ops(reset_ctl->dev);

	debug("%s(reset_ctl=%p)\n", __func__, reset_ctl);

	return ops->rst_status(reset_ctl);
}

int reset_release_all(struct reset_ctl *reset_ctl, int count)
{
	int i, ret;

	for (i = 0; i < count; i++) {
		debug("%s(reset_ctl[%d]=%p)\n", __func__, i, &reset_ctl[i]);

		/* check if reset has been previously requested */
		if (!reset_ctl[i].dev)
			continue;

		ret = reset_assert(&reset_ctl[i]);
		if (ret)
			return ret;

		ret = reset_free(&reset_ctl[i]);
		if (ret)
			return ret;
	}

	return 0;
}

static void devm_reset_release(struct udevice *dev, void *res)
{
	reset_free(res);
}

struct reset_ctl *devm_reset_control_get_by_index(struct udevice *dev,
						  int index)
{
	int rc;
	struct reset_ctl *reset_ctl;

	reset_ctl = devres_alloc(devm_reset_release, sizeof(struct reset_ctl),
				 __GFP_ZERO);
	if (unlikely(!reset_ctl))
		return ERR_PTR(-ENOMEM);

	rc = reset_get_by_index(dev, index, reset_ctl);
	if (rc)
		return ERR_PTR(rc);

	devres_add(dev, reset_ctl);
	return reset_ctl;
}

struct reset_ctl *devm_reset_control_get(struct udevice *dev, const char *id)
{
	int rc;
	struct reset_ctl *reset_ctl;

	reset_ctl = devres_alloc(devm_reset_release, sizeof(struct reset_ctl),
				 __GFP_ZERO);
	if (unlikely(!reset_ctl))
		return ERR_PTR(-ENOMEM);

	rc = reset_get_by_name(dev, id, reset_ctl);
	if (rc)
		return ERR_PTR(rc);

	devres_add(dev, reset_ctl);
	return reset_ctl;
}

struct reset_ctl *devm_reset_control_get_optional(struct udevice *dev,
						  const char *id)
{
	struct reset_ctl *r = devm_reset_control_get(dev, id);

	if (IS_ERR(r))
		return NULL;

	return r;
}

static void devm_reset_bulk_release(struct udevice *dev, void *res)
{
	struct reset_ctl_bulk *bulk = res;

	reset_release_all(bulk->resets, bulk->count);
}

struct reset_ctl_bulk *devm_reset_bulk_get_by_node(struct udevice *dev,
						   ofnode node)
{
	int rc;
	struct reset_ctl_bulk *bulk;

	bulk = devres_alloc(devm_reset_bulk_release,
			    sizeof(struct reset_ctl_bulk),
			    __GFP_ZERO);
	if (unlikely(!bulk))
		return ERR_PTR(-ENOMEM);

	rc = __reset_get_bulk(dev, node, bulk);
	if (rc)
		return ERR_PTR(rc);

	devres_add(dev, bulk);
	return bulk;
}

struct reset_ctl_bulk *devm_reset_bulk_get_optional_by_node(struct udevice *dev,
							    ofnode node)
{
	struct reset_ctl_bulk *bulk;

	bulk = devm_reset_bulk_get_by_node(dev, node);

	if (IS_ERR(bulk))
		return NULL;

	return bulk;
}

struct reset_ctl_bulk *devm_reset_bulk_get(struct udevice *dev)
{
	return devm_reset_bulk_get_by_node(dev, dev_ofnode(dev));
}

struct reset_ctl_bulk *devm_reset_bulk_get_optional(struct udevice *dev)
{
	return devm_reset_bulk_get_optional_by_node(dev, dev_ofnode(dev));
}

UCLASS_DRIVER(reset) = {
	.id		= UCLASS_RESET,
	.name		= "reset",
};
