This makes it possible to support drivers that use fwnode_property_get_reference_args() function.
Unified · Split
| @@ -560,6 +560,52 @@ software_node_get_named_child_node(const struct fwnode_handle *fwnode, · 559 unmodified lines | ||
| 560 | 560 | return NULL; |
| 561 | 561 | } |
| 562 | 562 | |
| 563 | +static int | |
| 564 | +software_node_get_reference_args(const struct fwnode_handle *fwnode, | |
| 565 | + const char *propname, const char *nargs_prop, | |
| 566 | + unsigned int nargs, unsigned int index, | |
| 567 | + struct fwnode_reference_args *args) | |
| 568 | +{ | |
| 569 | + struct swnode *swnode = to_swnode(fwnode); | |
| 570 | + const struct software_node_reference *ref; | |
| 571 | + const struct property_entry *prop; | |
| 572 | + struct fwnode_handle *refnode; | |
| 573 | + int i; | |
| 574 | + | |
| 575 | + if (!swnode || !swnode->node->references) | |
| 576 | + return -ENOENT; | |
| 577 | + | |
| 578 | + for (ref = swnode->node->references; ref->name; ref++) | |
| 579 | + if (!strcmp(ref->name, propname)) | |
| 580 | + break; | |
| 581 | + | |
| 582 | + if (!ref->name || index > (ref->nrefs - 1)) | |
| 583 | + return -ENOENT; | |
| 584 | + | |
| 585 | + refnode = software_node_fwnode(ref->refs[index].node); | |
| 586 | + if (!refnode) | |
| 587 | + return -ENOENT; | |
| 588 | + | |
| 589 | + if (nargs_prop) { | |
| 590 | + prop = property_entry_get(swnode->node->properties, nargs_prop); | |
| 591 | + if (!prop) | |
| 592 | + return -EINVAL; | |
| 593 | + | |
| 594 | + nargs = prop->value.u32_data; | |
| 595 | + } | |
| 596 | + | |
| 597 | + if (nargs > NR_FWNODE_REFERENCE_ARGS) | |
| 598 | + return -EINVAL; | |
| 599 | + | |
| 600 | + args->fwnode = software_node_get(refnode); | |
| 601 | + args->nargs = nargs; | |
| 602 | + | |
| 603 | + for (i = 0; i < nargs; i++) | |
| 604 | + args->args[i] = ref->refs[index].args[i]; | |
| 605 | + | |
| 606 | + return 0; | |
| 607 | +} | |
| 608 | + | |
| 563 | 609 | static const struct fwnode_operations software_node_ops = { |
| 564 | 610 | .get = software_node_get, |
| 565 | 611 | .put = software_node_put, |
| @@ -569,6 +615,7 @@ static const struct fwnode_operations software_node_ops = { · 3 unmodified lines | ||
| 569 | 615 | .get_parent = software_node_get_parent, |
| 570 | 616 | .get_next_child_node = software_node_get_next_child, |
| 571 | 617 | .get_named_child_node = software_node_get_named_child_node, |
| 618 | + .get_reference_args = software_node_get_reference_args | |
| 572 | 619 | }; |
| 573 | 620 | |
| 574 | 621 | /* -------------------------------------------------------------------------- */ |
| @@ -332,16 +332,44 @@ int fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode, · 331 unmodified lines | ||
| 332 | 332 | /* -------------------------------------------------------------------------- */ |
| 333 | 333 | /* Software fwnode support - when HW description is incomplete or missing */ |
| 334 | 334 | |
| 335 | +struct software_node; | |
| 336 | + | |
| 337 | +/** | |
| 338 | + * struct software_node_ref_args - Reference with additional arguments | |
| 339 | + * @node: Reference to a software node | |
| 340 | + * @nargs: Number of elements in @args array | |
| 341 | + * @args: Integer arguments | |
| 342 | + */ | |
| 343 | +struct software_node_ref_args { | |
| 344 | + const struct software_node *node; | |
| 345 | + unsigned int nargs; | |
| 346 | + u64 args[NR_FWNODE_REFERENCE_ARGS]; | |
| 347 | +}; | |
| 348 | + | |
| 349 | +/** | |
| 350 | + * struct software_node_reference - Named software node reference property | |
| 351 | + * @name: Name of the property | |
| 352 | + * @nrefs: Number of elements in @refs array | |
| 353 | + * @refs: Array of references with optional arguments | |
| 354 | + */ | |
| 355 | +struct software_node_reference { | |
| 356 | + const char *name; | |
| 357 | + unsigned int nrefs; | |
| 358 | + const struct software_node_ref_args *refs; | |
| 359 | +}; | |
| 360 | + | |
| 335 | 361 | /** |
| 336 | 362 | * struct software_node - Software node description |
| 337 | 363 | * @name: Name of the software node |
| 338 | 364 | * @parent: Parent of the software node |
| 339 | 365 | * @properties: Array of device properties |
| 366 | + * @references: Array of software node reference properties | |
| 340 | 367 | */ |
| 341 | 368 | struct software_node { |
| 342 | 369 | const char *name; |
| 343 | 370 | const struct software_node *parent; |
| 344 | 371 | const struct property_entry *properties; |
| 372 | + const struct software_node_reference *references; | |
| 345 | 373 | }; |
| 346 | 374 | |
| 347 | 375 | bool is_software_node(const struct fwnode_handle *fwnode); |