xref: /rk3399_rockchip-uboot/drivers/reset/reset-uclass.c (revision 9bd5cdf6b62b249dc48a00a23b44dc7be547f9f9)
189c1e2daSStephen Warren /*
289c1e2daSStephen Warren  * Copyright (c) 2016, NVIDIA CORPORATION.
389c1e2daSStephen Warren  *
489c1e2daSStephen Warren  * SPDX-License-Identifier: GPL-2.0
589c1e2daSStephen Warren  */
689c1e2daSStephen Warren 
789c1e2daSStephen Warren #include <common.h>
889c1e2daSStephen Warren #include <dm.h>
989c1e2daSStephen Warren #include <fdtdec.h>
1089c1e2daSStephen Warren #include <reset.h>
1189c1e2daSStephen Warren #include <reset-uclass.h>
1289c1e2daSStephen Warren 
1389c1e2daSStephen Warren DECLARE_GLOBAL_DATA_PTR;
1489c1e2daSStephen Warren 
1589c1e2daSStephen Warren static inline struct reset_ops *reset_dev_ops(struct udevice *dev)
1689c1e2daSStephen Warren {
1789c1e2daSStephen Warren 	return (struct reset_ops *)dev->driver->ops;
1889c1e2daSStephen Warren }
1989c1e2daSStephen Warren 
2089c1e2daSStephen Warren static int reset_of_xlate_default(struct reset_ctl *reset_ctl,
2140a475e8SSimon Glass 				  struct ofnode_phandle_args *args)
2289c1e2daSStephen Warren {
2389c1e2daSStephen Warren 	debug("%s(reset_ctl=%p)\n", __func__, reset_ctl);
2489c1e2daSStephen Warren 
2589c1e2daSStephen Warren 	if (args->args_count != 1) {
2689c1e2daSStephen Warren 		debug("Invaild args_count: %d\n", args->args_count);
2789c1e2daSStephen Warren 		return -EINVAL;
2889c1e2daSStephen Warren 	}
2989c1e2daSStephen Warren 
3089c1e2daSStephen Warren 	reset_ctl->id = args->args[0];
3189c1e2daSStephen Warren 
3289c1e2daSStephen Warren 	return 0;
3389c1e2daSStephen Warren }
3489c1e2daSStephen Warren 
3589c1e2daSStephen Warren int reset_get_by_index(struct udevice *dev, int index,
3689c1e2daSStephen Warren 		       struct reset_ctl *reset_ctl)
3789c1e2daSStephen Warren {
3840a475e8SSimon Glass 	struct ofnode_phandle_args args;
3989c1e2daSStephen Warren 	int ret;
4089c1e2daSStephen Warren 	struct udevice *dev_reset;
4189c1e2daSStephen Warren 	struct reset_ops *ops;
4289c1e2daSStephen Warren 
4389c1e2daSStephen Warren 	debug("%s(dev=%p, index=%d, reset_ctl=%p)\n", __func__, dev, index,
4489c1e2daSStephen Warren 	      reset_ctl);
4589c1e2daSStephen Warren 
4640a475e8SSimon Glass 	ret = dev_read_phandle_with_args(dev, "resets", "#reset-cells", 0,
4789c1e2daSStephen Warren 					  index, &args);
4889c1e2daSStephen Warren 	if (ret) {
4940a475e8SSimon Glass 		debug("%s: fdtdec_parse_phandle_with_args() failed: %d\n",
5089c1e2daSStephen Warren 		      __func__, ret);
5189c1e2daSStephen Warren 		return ret;
5289c1e2daSStephen Warren 	}
5389c1e2daSStephen Warren 
5440a475e8SSimon Glass 	ret = uclass_get_device_by_ofnode(UCLASS_RESET, args.node,
5589c1e2daSStephen Warren 					  &dev_reset);
5689c1e2daSStephen Warren 	if (ret) {
5740a475e8SSimon Glass 		debug("%s: uclass_get_device_by_ofnode() failed: %d\n",
5889c1e2daSStephen Warren 		      __func__, ret);
5940a475e8SSimon Glass 		debug("%s %d\n", ofnode_get_name(args.node), args.args[0]);
6089c1e2daSStephen Warren 		return ret;
6189c1e2daSStephen Warren 	}
6289c1e2daSStephen Warren 	ops = reset_dev_ops(dev_reset);
6389c1e2daSStephen Warren 
6489c1e2daSStephen Warren 	reset_ctl->dev = dev_reset;
6589c1e2daSStephen Warren 	if (ops->of_xlate)
6689c1e2daSStephen Warren 		ret = ops->of_xlate(reset_ctl, &args);
6789c1e2daSStephen Warren 	else
6889c1e2daSStephen Warren 		ret = reset_of_xlate_default(reset_ctl, &args);
6989c1e2daSStephen Warren 	if (ret) {
7089c1e2daSStephen Warren 		debug("of_xlate() failed: %d\n", ret);
7189c1e2daSStephen Warren 		return ret;
7289c1e2daSStephen Warren 	}
7389c1e2daSStephen Warren 
7489c1e2daSStephen Warren 	ret = ops->request(reset_ctl);
7589c1e2daSStephen Warren 	if (ret) {
7689c1e2daSStephen Warren 		debug("ops->request() failed: %d\n", ret);
7789c1e2daSStephen Warren 		return ret;
7889c1e2daSStephen Warren 	}
7989c1e2daSStephen Warren 
8089c1e2daSStephen Warren 	return 0;
8189c1e2daSStephen Warren }
8289c1e2daSStephen Warren 
8389c1e2daSStephen Warren int reset_get_by_name(struct udevice *dev, const char *name,
8489c1e2daSStephen Warren 		     struct reset_ctl *reset_ctl)
8589c1e2daSStephen Warren {
8689c1e2daSStephen Warren 	int index;
8789c1e2daSStephen Warren 
8889c1e2daSStephen Warren 	debug("%s(dev=%p, name=%s, reset_ctl=%p)\n", __func__, dev, name,
8989c1e2daSStephen Warren 	      reset_ctl);
9089c1e2daSStephen Warren 
9140a475e8SSimon Glass 	index = dev_read_stringlist_search(dev, "reset-names", name);
9289c1e2daSStephen Warren 	if (index < 0) {
93b02e4044SSimon Glass 		debug("fdt_stringlist_search() failed: %d\n", index);
9489c1e2daSStephen Warren 		return index;
9589c1e2daSStephen Warren 	}
9689c1e2daSStephen Warren 
9789c1e2daSStephen Warren 	return reset_get_by_index(dev, index, reset_ctl);
9889c1e2daSStephen Warren }
9989c1e2daSStephen Warren 
100*9bd5cdf6SPatrice Chotard int reset_request(struct reset_ctl *reset_ctl)
101*9bd5cdf6SPatrice Chotard {
102*9bd5cdf6SPatrice Chotard 	struct reset_ops *ops = reset_dev_ops(reset_ctl->dev);
103*9bd5cdf6SPatrice Chotard 
104*9bd5cdf6SPatrice Chotard 	debug("%s(reset_ctl=%p)\n", __func__, reset_ctl);
105*9bd5cdf6SPatrice Chotard 
106*9bd5cdf6SPatrice Chotard 	return ops->request(reset_ctl);
107*9bd5cdf6SPatrice Chotard }
108*9bd5cdf6SPatrice Chotard 
10989c1e2daSStephen Warren int reset_free(struct reset_ctl *reset_ctl)
11089c1e2daSStephen Warren {
11189c1e2daSStephen Warren 	struct reset_ops *ops = reset_dev_ops(reset_ctl->dev);
11289c1e2daSStephen Warren 
11389c1e2daSStephen Warren 	debug("%s(reset_ctl=%p)\n", __func__, reset_ctl);
11489c1e2daSStephen Warren 
11589c1e2daSStephen Warren 	return ops->free(reset_ctl);
11689c1e2daSStephen Warren }
11789c1e2daSStephen Warren 
11889c1e2daSStephen Warren int reset_assert(struct reset_ctl *reset_ctl)
11989c1e2daSStephen Warren {
12089c1e2daSStephen Warren 	struct reset_ops *ops = reset_dev_ops(reset_ctl->dev);
12189c1e2daSStephen Warren 
12289c1e2daSStephen Warren 	debug("%s(reset_ctl=%p)\n", __func__, reset_ctl);
12389c1e2daSStephen Warren 
12489c1e2daSStephen Warren 	return ops->rst_assert(reset_ctl);
12589c1e2daSStephen Warren }
12689c1e2daSStephen Warren 
12789c1e2daSStephen Warren int reset_deassert(struct reset_ctl *reset_ctl)
12889c1e2daSStephen Warren {
12989c1e2daSStephen Warren 	struct reset_ops *ops = reset_dev_ops(reset_ctl->dev);
13089c1e2daSStephen Warren 
13189c1e2daSStephen Warren 	debug("%s(reset_ctl=%p)\n", __func__, reset_ctl);
13289c1e2daSStephen Warren 
13389c1e2daSStephen Warren 	return ops->rst_deassert(reset_ctl);
13489c1e2daSStephen Warren }
13589c1e2daSStephen Warren 
13689c1e2daSStephen Warren UCLASS_DRIVER(reset) = {
13789c1e2daSStephen Warren 	.id		= UCLASS_RESET,
13889c1e2daSStephen Warren 	.name		= "reset",
13989c1e2daSStephen Warren };
140