Blame view
drivers/core/lists.c
5.09 KB
83d290c56 SPDX: Convert all... |
1 |
// SPDX-License-Identifier: GPL-2.0+ |
6494d708b dm: Add base driv... |
2 3 4 5 6 |
/* * Copyright (c) 2013 Google, Inc * * (C) Copyright 2012 * Marek Vasut <marex@denx.de> |
6494d708b dm: Add base driv... |
7 |
*/ |
d3e773613 dm: core: Use U-B... |
8 |
#define LOG_CATEGORY LOGC_DM |
6494d708b dm: Add base driv... |
9 10 11 12 |
#include <common.h> #include <errno.h> #include <dm/device.h> #include <dm/device-internal.h> |
fd536d818 dm: add missing i... |
13 |
#include <dm/lists.h> |
6494d708b dm: Add base driv... |
14 15 16 |
#include <dm/platdata.h> #include <dm/uclass.h> #include <dm/util.h> |
6a6d8fbef dm: Add missing h... |
17 |
#include <fdtdec.h> |
6494d708b 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 dm: Add base driv... |
26 |
|
6494d708b dm: Add base driv... |
27 |
for (entry = drv; entry != drv + n_ents; entry++) { |
2cede453d dm: simplify the ... |
28 |
if (!strcmp(name, entry->name)) |
6494d708b 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 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 dm: Allow drivers... |
49 |
int lists_bind_drivers(struct udevice *parent, bool pre_reloc_only) |
6494d708b 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 dm: rename device... |
55 |
struct udevice *dev; |
6494d708b dm: Add base driv... |
56 57 58 59 |
int result = 0; int ret; for (entry = info; entry != info + n_ents; entry++) { |
00606d7e3 dm: Allow drivers... |
60 61 |
ret = device_bind_by_name(parent, pre_reloc_only, entry, &dev); if (ret && ret != -EPERM) { |
6494d708b 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 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 dm: core: Update ... |
74 75 |
return device_bind_driver_to_node(parent, drv_name, dev_name, ofnode_null(), devp); |
5b9000dd2 dm: core: Add a f... |
76 77 78 |
} int device_bind_driver_to_node(struct udevice *parent, const char *drv_name, |
45a26867e dm: core: Update ... |
79 |
const char *dev_name, ofnode node, |
5b9000dd2 dm: core: Add a f... |
80 81 |
struct udevice **devp) { |
e33dc221f dm: Add a functio... |
82 83 84 85 86 |
struct driver *drv; int ret; drv = lists_driver_lookup_name(drv_name); if (!drv) { |
3039811e6 dm: core: Use deb... |
87 88 |
debug("Cannot find driver '%s' ", drv_name); |
e33dc221f dm: Add a functio... |
89 90 |
return -ENOENT; } |
45a26867e dm: core: Update ... |
91 92 |
ret = device_bind_with_driver_data(parent, drv, dev_name, 0 /* data */, node, devp); |
e33dc221f dm: Add a functio... |
93 |
|
45a26867e dm: core: Update ... |
94 |
return ret; |
e33dc221f dm: Add a functio... |
95 |
} |
29629eb89 dm: core: Don't u... |
96 |
#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) |
6494d708b dm: Add base driv... |
97 |
/** |
ce7017215 dm: core: Match c... |
98 |
* driver_check_compatible() - Check if a driver matches a compatible string |
6494d708b dm: Add base driv... |
99 |
* |
2ef249b44 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 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 dm: Add base driv... |
104 |
*/ |
ce7017215 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 dm: Add base driv... |
108 |
{ |
6494d708b dm: Add base driv... |
109 110 111 112 |
if (!of_match) return -ENOENT; while (of_match->compatible) { |
ce7017215 dm: core: Match c... |
113 |
if (!strcmp(of_match->compatible, compat)) { |
2ef249b44 dm: core: Allow a... |
114 |
*of_idp = of_match; |
6494d708b dm: Add base driv... |
115 |
return 0; |
2ef249b44 dm: core: Allow a... |
116 |
} |
6494d708b dm: Add base driv... |
117 118 119 120 121 |
of_match++; } return -ENOENT; } |
8d773c4ab dm: core: Respect... |
122 123 |
int lists_bind_fdt(struct udevice *parent, ofnode node, struct udevice **devp, bool pre_reloc_only) |
6494d708b 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 dm: core: Allow a... |
127 |
const struct udevice_id *id; |
6494d708b dm: Add base driv... |
128 |
struct driver *entry; |
54c5d08a0 dm: rename device... |
129 |
struct udevice *dev; |
9b0ba067f dm: Improve error... |
130 |
bool found = false; |
ce7017215 dm: core: Match c... |
131 132 |
const char *name, *compat_list, *compat; int compat_length, i; |
6494d708b dm: Add base driv... |
133 |
int result = 0; |
9b0ba067f dm: Improve error... |
134 |
int ret = 0; |
6494d708b dm: Add base driv... |
135 |
|
1f359e361 dm: Adjust lists_... |
136 137 |
if (devp) *devp = NULL; |
f5b5719cd dm: core: Update ... |
138 |
name = ofnode_get_name(node); |
d3e773613 dm: core: Use U-B... |
139 140 |
log_debug("bind node %s ", name); |
ce7017215 dm: core: Match c... |
141 |
|
61e51babd dm: ofnode: renam... |
142 |
compat_list = ofnode_get_property(node, "compatible", &compat_length); |
ce7017215 dm: core: Match c... |
143 144 |
if (!compat_list) { if (compat_length == -FDT_ERR_NOTFOUND) { |
d3e773613 dm: core: Use U-B... |
145 146 147 |
log_debug("Device '%s' has no compatible string ", name); |
ce7017215 dm: core: Match c... |
148 |
return 0; |
6494d708b dm: Add base driv... |
149 |
} |
f5b5719cd dm: core: Update ... |
150 151 |
dm_warn("Device tree error at node '%s' ", name); |
ce7017215 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 dm: core: Use U-B... |
162 163 164 |
log_debug(" - attempt to match compatible string '%s' ", compat); |
ce7017215 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 dm: core: Respect... |
174 175 |
if (pre_reloc_only) { if (!dm_ofnode_pre_reloc(node) && |
7fc0c2b18 dm: Add a debug m... |
176 177 178 |
!(entry->flags & DM_FLAG_PRE_RELOC)) { log_debug("Skipping device pre-relocation "); |
8d773c4ab dm: core: Respect... |
179 |
return 0; |
7fc0c2b18 dm: Add a debug m... |
180 |
} |
8d773c4ab dm: core: Respect... |
181 |
} |
d3e773613 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 dm: allow setting... |
186 |
ret = device_bind_with_driver_data(parent, entry, name, |
f5b5719cd dm: core: Update ... |
187 |
id->data, node, &dev); |
9fdfadf8f dm: core: allow d... |
188 |
if (ret == -ENODEV) { |
d3e773613 dm: core: Use U-B... |
189 190 |
log_debug("Driver '%s' refuses to bind ", entry->name); |
9fdfadf8f dm: core: allow d... |
191 192 |
continue; } |
6494d708b dm: Add base driv... |
193 |
if (ret) { |
d062482b4 dm: core: Display... |
194 195 196 |
dm_warn("Error binding driver '%s': %d ", entry->name, ret); |
1f359e361 dm: Adjust lists_... |
197 |
return ret; |
9b0ba067f dm: Improve error... |
198 199 |
} else { found = true; |
1f359e361 dm: Adjust lists_... |
200 201 |
if (devp) *devp = dev; |
6494d708b dm: Add base driv... |
202 |
} |
9b0ba067f dm: Improve error... |
203 204 |
break; } |
ce7017215 dm: core: Match c... |
205 |
if (!found && !result && ret != -ENODEV) |
d3e773613 dm: core: Use U-B... |
206 207 |
log_debug("No match for node '%s' ", name); |
6494d708b dm: Add base driv... |
208 209 210 211 |
return result; } #endif |