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 | return NULL; | 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 | static const struct fwnode_operations software_node_ops = { | 609 | static const struct fwnode_operations software_node_ops = { |
| 564 | .get = software_node_get, | 610 | .get = software_node_get, |
| 565 | .put = software_node_put, | 611 | .put = software_node_put, |
| @@ -569,6 +615,7 @@ static const struct fwnode_operations software_node_ops = { · 3 unmodified lines | |||
| 569 | .get_parent = software_node_get_parent, | 615 | .get_parent = software_node_get_parent, |
| 570 | .get_next_child_node = software_node_get_next_child, | 616 | .get_next_child_node = software_node_get_next_child, |
| 571 | .get_named_child_node = software_node_get_named_child_node, | 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 | /* Software fwnode support - when HW description is incomplete or missing */ | 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 | * struct software_node - Software node description | 362 | * struct software_node - Software node description |
| 337 | * @name: Name of the software node | 363 | * @name: Name of the software node |
| 338 | * @parent: Parent of the software node | 364 | * @parent: Parent of the software node |
| 339 | * @properties: Array of device properties | 365 | * @properties: Array of device properties |
| 366 | * @references: Array of software node reference properties | ||
| 340 | */ | 367 | */ |
| 341 | struct software_node { | 368 | struct software_node { |
| 342 | const char *name; | 369 | const char *name; |
| 343 | const struct software_node *parent; | 370 | const struct software_node *parent; |
| 344 | const struct property_entry *properties; | 371 | const struct property_entry *properties; |
| 372 | const struct software_node_reference *references; | ||
| 345 | }; | 373 | }; |
| 346 | 374 | ||
| 347 | bool is_software_node(const struct fwnode_handle *fwnode); | 375 | bool is_software_node(const struct fwnode_handle *fwnode); |