"Das U-Boot" Source Tree
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge patch series "dm: core: Support same compatible in host/gadget musb drivers"

Markus Schneider-Pargmann (TI.com) <msp@baylibre.com> says:

musb currently uses a wrapper driver that binds on the parent device of
the actual musb devices to manage the differentiation between gadget and
host modes. However in the upstream devicetree this parent devicetree
node can not be used to match the wrapper driver.

To be able to probe the musb devices in host/gadget mode directly, this
series introduces support for returning -ENODEV in bind functions
resulting in iterating the remaining drivers potentially binding to
other drivers that match the compatible.

Link: https://lore.kernel.org/r/20260127-topic-musb-probing-v2026-01-v4-0-ea3201e0f809@baylibre.com

Tom Rini e8ec8d98 cd4f4f74

+81 -37
+4
arch/sandbox/dts/test.dts
··· 457 457 mux-control-names = "mux0"; 458 458 }; 459 459 460 + multimatch-test { 461 + compatible = "sandbox,multimatch-test"; 462 + }; 463 + 460 464 phy_provider0: gen_phy@0 { 461 465 compatible = "sandbox,phy"; 462 466 #phy-cells = <1>;
+36 -37
drivers/core/lists.c
··· 204 204 const struct udevice_id *id; 205 205 struct driver *entry; 206 206 struct udevice *dev; 207 - bool found = false; 208 207 const char *name, *compat_list, *compat; 209 208 int compat_length, i; 210 - int result = 0; 211 209 int ret = 0; 212 210 213 211 if (devp) ··· 237 235 log_debug(" - attempt to match compatible string '%s'\n", 238 236 compat); 239 237 240 - id = NULL; 241 238 for (entry = driver; entry != driver + n_ents; entry++) { 239 + /* Search for drivers with matching drv or existing of_match */ 242 240 if (drv) { 243 241 if (drv != entry) 244 242 continue; 245 - if (!entry->of_match) 246 - break; 243 + } else if (!entry->of_match) { 244 + continue; 245 + } 246 + 247 + id = NULL; 248 + if (entry->of_match) { 249 + ret = driver_check_compatible(entry->of_match, &id, 250 + compat); 251 + if (ret) 252 + continue; 253 + log_debug(" - found match at driver '%s' for '%s'\n", 254 + entry->name, id->compatible); 255 + } 256 + 257 + if (pre_reloc_only) { 258 + if (!ofnode_pre_reloc(node) && 259 + !(entry->flags & DM_FLAG_PRE_RELOC)) { 260 + log_debug("Skipping device pre-relocation\n"); 261 + return 0; 262 + } 247 263 } 248 - ret = driver_check_compatible(entry->of_match, &id, 249 - compat); 250 - if (!ret) 251 - break; 252 - } 253 - if (entry == driver + n_ents) 254 - continue; 255 264 256 - if (pre_reloc_only) { 257 - if (!ofnode_pre_reloc(node) && 258 - !(entry->flags & DM_FLAG_PRE_RELOC)) { 259 - log_debug("Skipping device pre-relocation\n"); 260 - return 0; 265 + ret = device_bind_with_driver_data(parent, entry, name, 266 + id ? id->data : 0, node, 267 + &dev); 268 + if (!drv && ret == -ENODEV) { 269 + log_debug(" - Driver '%s' refuses to bind\n", entry->name); 270 + continue; 261 271 } 262 - } 272 + if (ret) { 273 + dm_warn("Error binding driver '%s': %d\n", entry->name, 274 + ret); 275 + return log_msg_ret("bind", ret); 276 + } 263 277 264 - if (entry->of_match) 265 - log_debug(" - found match at driver '%s' for '%s'\n", 266 - entry->name, id->compatible); 267 - ret = device_bind_with_driver_data(parent, entry, name, 268 - id ? id->data : 0, node, 269 - &dev); 270 - if (ret == -ENODEV) { 271 - log_debug("Driver '%s' refuses to bind\n", entry->name); 272 - continue; 273 - } 274 - if (ret) { 275 - dm_warn("Error binding driver '%s': %d\n", entry->name, 276 - ret); 277 - return log_msg_ret("bind", ret); 278 - } else { 279 - found = true; 280 278 if (devp) 281 279 *devp = dev; 280 + 281 + return 0; 282 282 } 283 - break; 284 283 } 285 284 286 - if (!found && !result && ret != -ENODEV) 285 + if (ret != -ENODEV) 287 286 log_debug("No match for node '%s'\n", name); 288 287 289 - return result; 288 + return 0; 290 289 } 291 290 #endif
+15
test/dm/core.c
··· 1410 1410 return 0; 1411 1411 } 1412 1412 DM_TEST(dm_test_try_first_device, 0); 1413 + 1414 + /* Test that all drivers are iterated when bind returns -ENODEV */ 1415 + static int dm_test_multimatch(struct unit_test_state *uts) 1416 + { 1417 + struct udevice *dev; 1418 + 1419 + ut_assertok(uclass_find_device_by_name(UCLASS_TEST, "multimatch-test", 1420 + &dev)); 1421 + ut_assertnonnull(dev); 1422 + ut_asserteq_str("test_multimatch_second", dev->driver->name); 1423 + ut_asserteq(2, dm_testdrv_op_count[DM_TEST_OP_BIND]); 1424 + 1425 + return 0; 1426 + } 1427 + DM_TEST(dm_test_multimatch, UTF_SCAN_FDT);
+26
test/dm/test-driver.c
··· 197 197 .unbind = test_manual_unbind, 198 198 .flags = DM_FLAG_VITAL | DM_FLAG_ACTIVE_DMA, 199 199 }; 200 + 201 + static int test_multimatch_first_bind(struct udevice *dev) 202 + { 203 + dm_testdrv_op_count[DM_TEST_OP_BIND]++; 204 + 205 + return -ENODEV; 206 + } 207 + 208 + static const struct udevice_id test_multimatch_ids[] = { 209 + { .compatible = "sandbox,multimatch-test" }, 210 + { } 211 + }; 212 + 213 + U_BOOT_DRIVER(test_multimatch_first) = { 214 + .name = "test_multimatch_first", 215 + .id = UCLASS_TEST, 216 + .of_match = test_multimatch_ids, 217 + .bind = test_multimatch_first_bind, 218 + }; 219 + 220 + U_BOOT_DRIVER(test_multimatch_second) = { 221 + .name = "test_multimatch_second", 222 + .id = UCLASS_TEST, 223 + .of_match = test_multimatch_ids, 224 + .bind = test_manual_bind, 225 + };