Blame view

drivers/reset/reset-uclass.c 2.78 KB
89c1e2da7   Stephen Warren   Add a reset drive...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
  /*
   * Copyright (c) 2016, NVIDIA CORPORATION.
   *
   * SPDX-License-Identifier: GPL-2.0
   */
  
  #include <common.h>
  #include <dm.h>
  #include <fdtdec.h>
  #include <reset.h>
  #include <reset-uclass.h>
  
  DECLARE_GLOBAL_DATA_PTR;
  
  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 fdtdec_phandle_args *args)
  {
  	debug("%s(reset_ctl=%p)
  ", __func__, reset_ctl);
  
  	if (args->args_count != 1) {
  		debug("Invaild args_count: %d
  ", args->args_count);
  		return -EINVAL;
  	}
  
  	reset_ctl->id = args->args[0];
  
  	return 0;
  }
  
  int reset_get_by_index(struct udevice *dev, int index,
  		       struct reset_ctl *reset_ctl)
  {
  	struct fdtdec_phandle_args args;
  	int ret;
  	struct udevice *dev_reset;
  	struct reset_ops *ops;
  
  	debug("%s(dev=%p, index=%d, reset_ctl=%p)
  ", __func__, dev, index,
  	      reset_ctl);
e160f7d43   Simon Glass   dm: core: Replace...
48
  	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
89c1e2da7   Stephen Warren   Add a reset drive...
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
  					     "resets", "#reset-cells", 0,
  					     index, &args);
  	if (ret) {
  		debug("%s: fdtdec_parse_phandle_with_args failed: %d
  ",
  		      __func__, ret);
  		return ret;
  	}
  
  	ret = uclass_get_device_by_of_offset(UCLASS_RESET, args.node,
  					     &dev_reset);
  	if (ret) {
  		debug("%s: uclass_get_device_by_of_offset failed: %d
  ",
  		      __func__, ret);
  		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
  ", ret);
  		return ret;
  	}
  
  	ret = ops->request(reset_ctl);
  	if (ret) {
  		debug("ops->request() failed: %d
  ", ret);
  		return ret;
  	}
  
  	return 0;
  }
  
  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)
  ", __func__, dev, name,
  	      reset_ctl);
e160f7d43   Simon Glass   dm: core: Replace...
97
  	index = fdt_stringlist_search(gd->fdt_blob, dev_of_offset(dev),
b02e4044f   Simon Glass   libfdt: Bring in ...
98
  				      "reset-names", name);
89c1e2da7   Stephen Warren   Add a reset drive...
99
  	if (index < 0) {
b02e4044f   Simon Glass   libfdt: Bring in ...
100
101
  		debug("fdt_stringlist_search() failed: %d
  ", index);
89c1e2da7   Stephen Warren   Add a reset drive...
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
  		return index;
  	}
  
  	return reset_get_by_index(dev, index, 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)
  ", __func__, reset_ctl);
  
  	return ops->free(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)
  ", __func__, reset_ctl);
  
  	return ops->rst_assert(reset_ctl);
  }
  
  int reset_deassert(struct reset_ctl *reset_ctl)
  {
  	struct reset_ops *ops = reset_dev_ops(reset_ctl->dev);
  
  	debug("%s(reset_ctl=%p)
  ", __func__, reset_ctl);
  
  	return ops->rst_deassert(reset_ctl);
  }
  
  UCLASS_DRIVER(reset) = {
  	.id		= UCLASS_RESET,
  	.name		= "reset",
  };