mirror of https://github.com/torvalds/linux.git
software node: allow referencing firmware nodes
At the moment software nodes can only reference other software nodes. This is a limitation for devices created, for instance, on the auxiliary bus with a dynamic software node attached which cannot reference devices the firmware node of which is "real" (as an OF node or otherwise). Make it possible for a software node to reference all firmware nodes in addition to static software nodes. To that end: add a second pointer to struct software_node_ref_args of type struct fwnode_handle. The core swnode code will first check the swnode pointer and if it's NULL, it will assume the fwnode pointer should be set. Software node graphs remain the same, as in: the remote endpoints still have to be software nodes. Acked-by: Linus Walleij <linus.walleij@linaro.org> Reviewed-by: Sakari Ailus <sakari.ailus@linux.intel.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com> Tested-by: Charles Keepax <ckeepax@opensource.cirrus.com> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
This commit is contained in:
parent
0651933c11
commit
d7cdbbc93c
|
|
@ -535,7 +535,24 @@ software_node_get_reference_args(const struct fwnode_handle *fwnode,
|
||||||
ref_array = prop->pointer;
|
ref_array = prop->pointer;
|
||||||
ref = &ref_array[index];
|
ref = &ref_array[index];
|
||||||
|
|
||||||
refnode = software_node_fwnode(ref->node);
|
/*
|
||||||
|
* A software node can reference other software nodes or firmware
|
||||||
|
* nodes (which are the abstraction layer sitting on top of them).
|
||||||
|
* This is done to ensure we can create references to static software
|
||||||
|
* nodes before they're registered with the firmware node framework.
|
||||||
|
* At the time the reference is being resolved, we expect the swnodes
|
||||||
|
* in question to already have been registered and to be backed by
|
||||||
|
* a firmware node. This is why we use the fwnode API below to read the
|
||||||
|
* relevant properties and bump the reference count.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (ref->swnode)
|
||||||
|
refnode = software_node_fwnode(ref->swnode);
|
||||||
|
else if (ref->fwnode)
|
||||||
|
refnode = ref->fwnode;
|
||||||
|
else
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
if (!refnode)
|
if (!refnode)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
|
|
@ -633,7 +650,10 @@ software_node_graph_get_remote_endpoint(const struct fwnode_handle *fwnode)
|
||||||
|
|
||||||
ref = prop->pointer;
|
ref = prop->pointer;
|
||||||
|
|
||||||
return software_node_get(software_node_fwnode(ref[0].node));
|
if (!ref->swnode)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return software_node_get(software_node_fwnode(ref->swnode));
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct fwnode_handle *
|
static struct fwnode_handle *
|
||||||
|
|
|
||||||
|
|
@ -355,19 +355,26 @@ struct software_node;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct software_node_ref_args - Reference property with additional arguments
|
* struct software_node_ref_args - Reference property with additional arguments
|
||||||
* @node: Reference to a software node
|
* @swnode: Reference to a software node
|
||||||
|
* @fwnode: Alternative reference to a firmware node handle
|
||||||
* @nargs: Number of elements in @args array
|
* @nargs: Number of elements in @args array
|
||||||
* @args: Integer arguments
|
* @args: Integer arguments
|
||||||
*/
|
*/
|
||||||
struct software_node_ref_args {
|
struct software_node_ref_args {
|
||||||
const struct software_node *node;
|
const struct software_node *swnode;
|
||||||
|
struct fwnode_handle *fwnode;
|
||||||
unsigned int nargs;
|
unsigned int nargs;
|
||||||
u64 args[NR_FWNODE_REFERENCE_ARGS];
|
u64 args[NR_FWNODE_REFERENCE_ARGS];
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SOFTWARE_NODE_REFERENCE(_ref_, ...) \
|
#define SOFTWARE_NODE_REFERENCE(_ref_, ...) \
|
||||||
(const struct software_node_ref_args) { \
|
(const struct software_node_ref_args) { \
|
||||||
.node = _ref_, \
|
.swnode = _Generic(_ref_, \
|
||||||
|
const struct software_node *: _ref_, \
|
||||||
|
default: NULL), \
|
||||||
|
.fwnode = _Generic(_ref_, \
|
||||||
|
struct fwnode_handle *: _ref_, \
|
||||||
|
default: NULL), \
|
||||||
.nargs = COUNT_ARGS(__VA_ARGS__), \
|
.nargs = COUNT_ARGS(__VA_ARGS__), \
|
||||||
.args = { __VA_ARGS__ }, \
|
.args = { __VA_ARGS__ }, \
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue