Blame view

drivers/core/lists.c 5.09 KB
83d290c56   Tom Rini   SPDX: Convert all...
1
  // SPDX-License-Identifier: GPL-2.0+
6494d708b   Simon Glass   dm: Add base driv...
2
3
4
5
6
  /*
   * Copyright (c) 2013 Google, Inc
   *
   * (C) Copyright 2012
   * Marek Vasut <marex@denx.de>
6494d708b   Simon Glass   dm: Add base driv...
7
   */
d3e773613   Simon Glass   dm: core: Use U-B...
8
  #define LOG_CATEGORY LOGC_DM
6494d708b   Simon Glass   dm: Add base driv...
9
10
11
12
  #include <common.h>
  #include <errno.h>
  #include <dm/device.h>
  #include <dm/device-internal.h>
fd536d818   Jeroen Hofstee   dm: add missing i...
13
  #include <dm/lists.h>
6494d708b   Simon Glass   dm: Add base driv...
14
15
16
  #include <dm/platdata.h>
  #include <dm/uclass.h>
  #include <dm/util.h>
6a6d8fbef   Simon Glass   dm: Add missing h...
17
  #include <fdtdec.h>
6494d708b   Simon Glass   dm: Add base driv...
18
19
20
21
22
23
24
25
  #include <linux/compiler.h>
  
  struct driver *lists_driver_lookup_name(const char *name)
  {
  	struct driver *drv =
  		ll_entry_start(struct driver, driver);
  	const int n_ents = ll_entry_count(struct driver, driver);
  	struct driver *entry;
6494d708b   Simon Glass   dm: Add base driv...
26

6494d708b   Simon Glass   dm: Add base driv...
27
  	for (entry = drv; entry != drv + n_ents; entry++) {
2cede453d   Masahiro Yamada   dm: simplify the ...
28
  		if (!strcmp(name, entry->name))
6494d708b   Simon Glass   dm: Add base driv...
29
30
31
32
33
34
35
36
37
38
39
40
41
  			return entry;
  	}
  
  	/* Not found */
  	return NULL;
  }
  
  struct uclass_driver *lists_uclass_lookup(enum uclass_id id)
  {
  	struct uclass_driver *uclass =
  		ll_entry_start(struct uclass_driver, uclass);
  	const int n_ents = ll_entry_count(struct uclass_driver, uclass);
  	struct uclass_driver *entry;
6494d708b   Simon Glass   dm: Add base driv...
42
43
44
45
46
47
48
  	for (entry = uclass; entry != uclass + n_ents; entry++) {
  		if (entry->id == id)
  			return entry;
  	}
  
  	return NULL;
  }
00606d7e3   Simon Glass   dm: Allow drivers...
49
  int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only)
6494d708b   Simon Glass   dm: Add base driv...
50
51
52
53
54
  {
  	struct driver_info *info =
  		ll_entry_start(struct driver_info, driver_info);
  	const int n_ents = ll_entry_count(struct driver_info, driver_info);
  	struct driver_info *entry;
54c5d08a0   Heiko Schocher   dm: rename device...
55
  	struct udevice *dev;
6494d708b   Simon Glass   dm: Add base driv...
56
57
58
59
  	int result = 0;
  	int ret;
  
  	for (entry = info; entry != info + n_ents; entry++) {
00606d7e3   Simon Glass   dm: Allow drivers...
60
61
  		ret = device_bind_by_name(parent, pre_reloc_only, entry, &dev);
  		if (ret && ret != -EPERM) {
6494d708b   Simon Glass   dm: Add base driv...
62
63
64
65
66
67
68
69
70
  			dm_warn("No match for driver '%s'
  ", entry->name);
  			if (!result || ret != -ENOENT)
  				result = ret;
  		}
  	}
  
  	return result;
  }
e33dc221f   Simon Glass   dm: Add a functio...
71
72
73
  int device_bind_driver(struct udevice *parent, const char *drv_name,
  		       const char *dev_name, struct udevice **devp)
  {
45a26867e   Simon Glass   dm: core: Update ...
74
75
  	return device_bind_driver_to_node(parent, drv_name, dev_name,
  					  ofnode_null(), devp);
5b9000dd2   Simon Glass   dm: core: Add a f...
76
77
78
  }
  
  int device_bind_driver_to_node(struct udevice *parent, const char *drv_name,
45a26867e   Simon Glass   dm: core: Update ...
79
  			       const char *dev_name, ofnode node,
5b9000dd2   Simon Glass   dm: core: Add a f...
80
81
  			       struct udevice **devp)
  {
e33dc221f   Simon Glass   dm: Add a functio...
82
83
84
85
86
  	struct driver *drv;
  	int ret;
  
  	drv = lists_driver_lookup_name(drv_name);
  	if (!drv) {
3039811e6   Simon Glass   dm: core: Use deb...
87
88
  		debug("Cannot find driver '%s'
  ", drv_name);
e33dc221f   Simon Glass   dm: Add a functio...
89
90
  		return -ENOENT;
  	}
45a26867e   Simon Glass   dm: core: Update ...
91
92
  	ret = device_bind_with_driver_data(parent, drv, dev_name, 0 /* data */,
  					   node, devp);
e33dc221f   Simon Glass   dm: Add a functio...
93

45a26867e   Simon Glass   dm: core: Update ...
94
  	return ret;
e33dc221f   Simon Glass   dm: Add a functio...
95
  }
29629eb89   Simon Glass   dm: core: Don't u...
96
  #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
6494d708b   Simon Glass   dm: Add base driv...
97
  /**
ce7017215   Paul Burton   dm: core: Match c...
98
   * driver_check_compatible() - Check if a driver matches a compatible string
6494d708b   Simon Glass   dm: Add base driv...
99
   *
2ef249b44   Simon Glass   dm: core: Allow a...
100
101
   * @param of_match:	List of compatible strings to match
   * @param of_idp:	Returns the match that was found
ce7017215   Paul Burton   dm: core: Match c...
102
103
   * @param compat:	The compatible string to search for
   * @return 0 if there is a match, -ENOENT if no match
6494d708b   Simon Glass   dm: Add base driv...
104
   */
ce7017215   Paul Burton   dm: core: Match c...
105
106
107
  static int driver_check_compatible(const struct udevice_id *of_match,
  				   const struct udevice_id **of_idp,
  				   const char *compat)
6494d708b   Simon Glass   dm: Add base driv...
108
  {
6494d708b   Simon Glass   dm: Add base driv...
109
110
111
112
  	if (!of_match)
  		return -ENOENT;
  
  	while (of_match->compatible) {
ce7017215   Paul Burton   dm: core: Match c...
113
  		if (!strcmp(of_match->compatible, compat)) {
2ef249b44   Simon Glass   dm: core: Allow a...
114
  			*of_idp = of_match;
6494d708b   Simon Glass   dm: Add base driv...
115
  			return 0;
2ef249b44   Simon Glass   dm: core: Allow a...
116
  		}
6494d708b   Simon Glass   dm: Add base driv...
117
118
119
120
121
  		of_match++;
  	}
  
  	return -ENOENT;
  }
8d773c4ab   Bin Meng   dm: core: Respect...
122
123
  int lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp,
  		   bool pre_reloc_only)
6494d708b   Simon Glass   dm: Add base driv...
124
125
126
  {
  	struct driver *driver = ll_entry_start(struct driver, driver);
  	const int n_ents = ll_entry_count(struct driver, driver);
2ef249b44   Simon Glass   dm: core: Allow a...
127
  	const struct udevice_id *id;
6494d708b   Simon Glass   dm: Add base driv...
128
  	struct driver *entry;
54c5d08a0   Heiko Schocher   dm: rename device...
129
  	struct udevice *dev;
9b0ba067f   Simon Glass   dm: Improve error...
130
  	bool found = false;
ce7017215   Paul Burton   dm: core: Match c...
131
132
  	const char *name, *compat_list, *compat;
  	int compat_length, i;
6494d708b   Simon Glass   dm: Add base driv...
133
  	int result = 0;
9b0ba067f   Simon Glass   dm: Improve error...
134
  	int ret = 0;
6494d708b   Simon Glass   dm: Add base driv...
135

1f359e361   Simon Glass   dm: Adjust lists_...
136
137
  	if (devp)
  		*devp = NULL;
f5b5719cd   Simon Glass   dm: core: Update ...
138
  	name = ofnode_get_name(node);
d3e773613   Simon Glass   dm: core: Use U-B...
139
140
  	log_debug("bind node %s
  ", name);
ce7017215   Paul Burton   dm: core: Match c...
141

61e51babd   Masahiro Yamada   dm: ofnode: renam...
142
  	compat_list = ofnode_get_property(node, "compatible", &compat_length);
ce7017215   Paul Burton   dm: core: Match c...
143
144
  	if (!compat_list) {
  		if (compat_length == -FDT_ERR_NOTFOUND) {
d3e773613   Simon Glass   dm: core: Use U-B...
145
146
147
  			log_debug("Device '%s' has no compatible string
  ",
  				  name);
ce7017215   Paul Burton   dm: core: Match c...
148
  			return 0;
6494d708b   Simon Glass   dm: Add base driv...
149
  		}
f5b5719cd   Simon Glass   dm: core: Update ...
150
151
  		dm_warn("Device tree error at node '%s'
  ", name);
ce7017215   Paul Burton   dm: core: Match c...
152
153
154
155
156
157
158
159
160
161
  		return compat_length;
  	}
  
  	/*
  	 * Walk through the compatible string list, attempting to match each
  	 * compatible string in order such that we match in order of priority
  	 * from the first string to the last.
  	 */
  	for (i = 0; i < compat_length; i += strlen(compat) + 1) {
  		compat = compat_list + i;
d3e773613   Simon Glass   dm: core: Use U-B...
162
163
164
  		log_debug("   - attempt to match compatible string '%s'
  ",
  			  compat);
ce7017215   Paul Burton   dm: core: Match c...
165
166
167
168
169
170
171
172
173
  
  		for (entry = driver; entry != driver + n_ents; entry++) {
  			ret = driver_check_compatible(entry->of_match, &id,
  						      compat);
  			if (!ret)
  				break;
  		}
  		if (entry == driver + n_ents)
  			continue;
8d773c4ab   Bin Meng   dm: core: Respect...
174
175
  		if (pre_reloc_only) {
  			if (!dm_ofnode_pre_reloc(node) &&
7fc0c2b18   Sean Anderson   dm: Add a debug m...
176
177
178
  			    !(entry->flags & DM_FLAG_PRE_RELOC)) {
  				log_debug("Skipping device pre-relocation
  ");
8d773c4ab   Bin Meng   dm: core: Respect...
179
  				return 0;
7fc0c2b18   Sean Anderson   dm: Add a debug m...
180
  			}
8d773c4ab   Bin Meng   dm: core: Respect...
181
  		}
d3e773613   Simon Glass   dm: core: Use U-B...
182
183
184
185
  		log_debug("   - found match at '%s': '%s' matches '%s'
  ",
  			  entry->name, entry->of_match->compatible,
  			  id->compatible);
daac3bfee   Stephen Warren   dm: allow setting...
186
  		ret = device_bind_with_driver_data(parent, entry, name,
f5b5719cd   Simon Glass   dm: core: Update ...
187
  						   id->data, node, &dev);
9fdfadf8f   Stephen Warren   dm: core: allow d...
188
  		if (ret == -ENODEV) {
d3e773613   Simon Glass   dm: core: Use U-B...
189
190
  			log_debug("Driver '%s' refuses to bind
  ", entry->name);
9fdfadf8f   Stephen Warren   dm: core: allow d...
191
192
  			continue;
  		}
6494d708b   Simon Glass   dm: Add base driv...
193
  		if (ret) {
d062482b4   Simon Glass   dm: core: Display...
194
195
196
  			dm_warn("Error binding driver '%s': %d
  ", entry->name,
  				ret);
1f359e361   Simon Glass   dm: Adjust lists_...
197
  			return ret;
9b0ba067f   Simon Glass   dm: Improve error...
198
199
  		} else {
  			found = true;
1f359e361   Simon Glass   dm: Adjust lists_...
200
201
  			if (devp)
  				*devp = dev;
6494d708b   Simon Glass   dm: Add base driv...
202
  		}
9b0ba067f   Simon Glass   dm: Improve error...
203
204
  		break;
  	}
ce7017215   Paul Burton   dm: core: Match c...
205
  	if (!found && !result && ret != -ENODEV)
d3e773613   Simon Glass   dm: core: Use U-B...
206
207
  		log_debug("No match for node '%s'
  ", name);
6494d708b   Simon Glass   dm: Add base driv...
208
209
210
211
  
  	return result;
  }
  #endif