xref: /rk3399_rockchip-uboot/drivers/reset/reset-uclass.c (revision b02e4044ff8ee1f6ac83917a39514172a9b449fb)
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,
2189c1e2daSStephen Warren 				  struct fdtdec_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 {
3889c1e2daSStephen Warren 	struct fdtdec_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 
4689c1e2daSStephen Warren 	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset,
4789c1e2daSStephen Warren 					     "resets", "#reset-cells", 0,
4889c1e2daSStephen Warren 					     index, &args);
4989c1e2daSStephen Warren 	if (ret) {
5089c1e2daSStephen Warren 		debug("%s: fdtdec_parse_phandle_with_args failed: %d\n",
5189c1e2daSStephen Warren 		      __func__, ret);
5289c1e2daSStephen Warren 		return ret;
5389c1e2daSStephen Warren 	}
5489c1e2daSStephen Warren 
5589c1e2daSStephen Warren 	ret = uclass_get_device_by_of_offset(UCLASS_RESET, args.node,
5689c1e2daSStephen Warren 					     &dev_reset);
5789c1e2daSStephen Warren 	if (ret) {
5889c1e2daSStephen Warren 		debug("%s: uclass_get_device_by_of_offset failed: %d\n",
5989c1e2daSStephen Warren 		      __func__, ret);
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 
91*b02e4044SSimon Glass 	index = fdt_stringlist_search(gd->fdt_blob, dev->of_offset,
92*b02e4044SSimon Glass 				      "reset-names", name);
9389c1e2daSStephen Warren 	if (index < 0) {
94*b02e4044SSimon Glass 		debug("fdt_stringlist_search() failed: %d\n", index);
9589c1e2daSStephen Warren 		return index;
9689c1e2daSStephen Warren 	}
9789c1e2daSStephen Warren 
9889c1e2daSStephen Warren 	return reset_get_by_index(dev, index, reset_ctl);
9989c1e2daSStephen Warren }
10089c1e2daSStephen Warren 
10189c1e2daSStephen Warren int reset_free(struct reset_ctl *reset_ctl)
10289c1e2daSStephen Warren {
10389c1e2daSStephen Warren 	struct reset_ops *ops = reset_dev_ops(reset_ctl->dev);
10489c1e2daSStephen Warren 
10589c1e2daSStephen Warren 	debug("%s(reset_ctl=%p)\n", __func__, reset_ctl);
10689c1e2daSStephen Warren 
10789c1e2daSStephen Warren 	return ops->free(reset_ctl);
10889c1e2daSStephen Warren }
10989c1e2daSStephen Warren 
11089c1e2daSStephen Warren int reset_assert(struct reset_ctl *reset_ctl)
11189c1e2daSStephen Warren {
11289c1e2daSStephen Warren 	struct reset_ops *ops = reset_dev_ops(reset_ctl->dev);
11389c1e2daSStephen Warren 
11489c1e2daSStephen Warren 	debug("%s(reset_ctl=%p)\n", __func__, reset_ctl);
11589c1e2daSStephen Warren 
11689c1e2daSStephen Warren 	return ops->rst_assert(reset_ctl);
11789c1e2daSStephen Warren }
11889c1e2daSStephen Warren 
11989c1e2daSStephen Warren int reset_deassert(struct reset_ctl *reset_ctl)
12089c1e2daSStephen Warren {
12189c1e2daSStephen Warren 	struct reset_ops *ops = reset_dev_ops(reset_ctl->dev);
12289c1e2daSStephen Warren 
12389c1e2daSStephen Warren 	debug("%s(reset_ctl=%p)\n", __func__, reset_ctl);
12489c1e2daSStephen Warren 
12589c1e2daSStephen Warren 	return ops->rst_deassert(reset_ctl);
12689c1e2daSStephen Warren }
12789c1e2daSStephen Warren 
12889c1e2daSStephen Warren UCLASS_DRIVER(reset) = {
12989c1e2daSStephen Warren 	.id		= UCLASS_RESET,
13089c1e2daSStephen Warren 	.name		= "reset",
13189c1e2daSStephen Warren };
132