Commit 4a3f421b authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

Merge branches 'acpica' and 'acpi-property'

Merge ACPICA changes and updates of the ACPI device properties
framework for 4.19.

These revert two ACPICA commits that are not needed any more and
modify the properties graph support in ACPI to be more in-line with
the analogous DT code.

* acpica:
  ACPICA: Update version to 20180629
  ACPICA: Revert "iASL compiler: allow compilation of externals with paths that refer to existing names"
  ACPICA: Revert "iASL: change processing of external op namespace nodes for correctness"

* acpi-property:
  ACPI: property: graph: Update graph documentation to use generic references
  ACPI: property: graph: Improve graph documentation for port/ep numbering
  ACPI: property: graph: Fix graph documentation
  ACPI: property: Update documentation for hierarchical data extension 1.1
  ACPI: property: Document key numbering for hierarchical data extension refs
  ACPI: property: Use data node name and reg property for graphs
  ACPI: property: Allow direct graph endpoint references
  ACPI: property: Make the ACPI graph API private
  ACPI: property: Document hierarchical data extension references
  ACPI: property: Allow making references to non-device nodes
  ACPI: Convert ACPI reference args to generic fwnode reference args
Copyright (C) 2018 Intel Corporation
Author: Sakari Ailus <sakari.ailus@linux.intel.com>
Referencing hierarchical data nodes
-----------------------------------
ACPI in general allows referring to device objects in the tree only.
Hierarchical data extension nodes may not be referred to directly, hence this
document defines a scheme to implement such references.
A reference consist of the device object name followed by one or more
hierarchical data extension [1] keys. Specifically, the hierarchical data
extension node which is referred to by the key shall lie directly under the
parent object i.e. either the device object or another hierarchical data
extension node.
The keys in the hierarchical data nodes shall consist of the name of the node,
"@" character and the number of the node in hexadecimal notation (without pre-
or postfixes). The same ACPI object shall include the _DSD property extension
with a property "reg" that shall have the same numerical value as the number of
the node.
In case a hierarchical data extensions node has no numerical value, then the
"reg" property shall be omitted from the ACPI object's _DSD properties and the
"@" character and the number shall be omitted from the hierarchical data
extension key.
Example
-------
In the ASL snippet below, the "reference" _DSD property [2] contains a
device object reference to DEV0 and under that device object, a
hierarchical data extension key "node@1" referring to the NOD1 object
and lastly, a hierarchical data extension key "anothernode" referring to
the ANOD object which is also the final target node of the reference.
Device (DEV0)
{
Name (_DSD, Package () {
ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
Package () {
Package () { "node@0", NOD0 },
Package () { "node@1", NOD1 },
}
})
Name (NOD0, Package() {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () { "random-property", 3 },
}
})
Name (NOD1, Package() {
ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
Package () {
Package () { "anothernode", ANOD },
}
})
Name (ANOD, Package() {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () { "random-property", 0 },
}
})
}
Device (DEV1)
{
Name (_DSD, Package () {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () {
Package () { "reference", ^DEV0, "node@1", "anothernode" },
}
})
}
Please also see a graph example in graph.txt .
References
----------
[1] Hierarchical Data Extension UUID For _DSD.
<URL:http://www.uefi.org/sites/default/files/resources/_DSD-hierarchical-data-extension-UUID-v1.1.pdf>,
referenced 2018-07-17.
[2] Device Properties UUID For _DSD.
<URL:http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf>,
referenced 2016-10-04.
...@@ -36,29 +36,41 @@ The port and endpoint concepts are very similar to those in Devicetree ...@@ -36,29 +36,41 @@ The port and endpoint concepts are very similar to those in Devicetree
[3]. A port represents an interface in a device, and an endpoint [3]. A port represents an interface in a device, and an endpoint
represents a connection to that interface. represents a connection to that interface.
All port nodes are located under the device's "_DSD" node in the All port nodes are located under the device's "_DSD" node in the hierarchical
hierarchical data extension tree. The property extension related to data extension tree. The data extension related to each port node must begin
each port node must contain the key "port" and an integer value which with "port" and must be followed by the "@" character and the number of the port
is the number of the port. The object it refers to should be called "PRTX", as its key. The target object it refers to should be called "PRTX", where "X" is
where "X" is the number of the port. the number of the port. An example of such a package would be:
Further on, endpoints are located under the individual port nodes. The Package() { "port@4", PRT4 }
first hierarchical data extension package list entry of the endpoint
nodes must begin with "endpoint" and must be followed by the number Further on, endpoints are located under the port nodes. The hierarchical
of the endpoint. The object it refers to should be called "EPXY", where data extension key of the endpoint nodes must begin with
"X" is the number of the port and "Y" is the number of the endpoint. "endpoint" and must be followed by the "@" character and the number of the
endpoint. The object it refers to should be called "EPXY", where "X" is the
Each port node contains a property extension key "port", the value of number of the port and "Y" is the number of the endpoint. An example of such a
which is the number of the port node. The each endpoint is similarly numbered package would be:
with a property extension key "endpoint". Port numbers must be unique within a
device and endpoint numbers must be unique within a port. Package() { "endpoint@0", EP40 }
Each port node contains a property extension key "port", the value of which is
the number of the port. Each endpoint is similarly numbered with a property
extension key "reg", the value of which is the number of the endpoint. Port
numbers must be unique within a device and endpoint numbers must be unique
within a port. If a device object may only has a single port, then the number
of that port shall be zero. Similarly, if a port may only have a single
endpoint, the number of that endpoint shall be zero.
The endpoint reference uses property extension with "remote-endpoint" property The endpoint reference uses property extension with "remote-endpoint" property
name followed by a reference in the same package. Such references consist of the name followed by a reference in the same package. Such references consist of the
the remote device reference, number of the port in the device and finally the the remote device reference, the first package entry of the port data extension
number of the endpoint in that port. Individual references thus appear as: reference under the device and finally the first package entry of the endpoint
data extension reference under the port. Individual references thus appear as:
Package() { device, port_number, endpoint_number } Package() { device, "port@X", "endpoint@Y" }
In the above example, "X" is the number of the port and "Y" is the number of the
endpoint.
The references to endpoints must be always done both ways, to the The references to endpoints must be always done both ways, to the
remote endpoint and back from the referred remote endpoint node. remote endpoint and back from the referred remote endpoint node.
...@@ -76,24 +88,24 @@ A simple example of this is show below: ...@@ -76,24 +88,24 @@ A simple example of this is show below:
}, },
ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
Package () { Package () {
Package () { "port0", "PRT0" }, Package () { "port@0", PRT0 },
} }
}) })
Name (PRT0, Package() { Name (PRT0, Package() {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () { Package () {
Package () { "port", 0 }, Package () { "reg", 0 },
}, },
ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
Package () { Package () {
Package () { "endpoint0", "EP00" }, Package () { "endpoint@0", EP00 },
} }
}) })
Name (EP00, Package() { Name (EP00, Package() {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () { Package () {
Package () { "endpoint", 0 }, Package () { "reg", 0 },
Package () { "remote-endpoint", Package() { \_SB.PCI0.ISP, 4, 0 } }, Package () { "remote-endpoint", Package() { \_SB.PCI0.ISP, "port@4", "endpoint@0" } },
} }
}) })
} }
...@@ -106,26 +118,26 @@ A simple example of this is show below: ...@@ -106,26 +118,26 @@ A simple example of this is show below:
Name (_DSD, Package () { Name (_DSD, Package () {
ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
Package () { Package () {
Package () { "port4", "PRT4" }, Package () { "port@4", PRT4 },
} }
}) })
Name (PRT4, Package() { Name (PRT4, Package() {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () { Package () {
Package () { "port", 4 }, /* CSI-2 port number */ Package () { "reg", 4 }, /* CSI-2 port number */
}, },
ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"),
Package () { Package () {
Package () { "endpoint0", "EP40" }, Package () { "endpoint@0", EP40 },
} }
}) })
Name (EP40, Package() { Name (EP40, Package() {
ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
Package () { Package () {
Package () { "endpoint", 0 }, Package () { "reg", 0 },
Package () { "remote-endpoint", Package () { \_SB.PCI0.I2C2.CAM0, 0, 0 } }, Package () { "remote-endpoint", Package () { \_SB.PCI0.I2C2.CAM0, "port@0", "endpoint@0" } },
} }
}) })
} }
...@@ -151,7 +163,7 @@ References ...@@ -151,7 +163,7 @@ References
referenced 2016-10-04. referenced 2016-10-04.
[5] Hierarchical Data Extension UUID For _DSD. [5] Hierarchical Data Extension UUID For _DSD.
<URL:http://www.uefi.org/sites/default/files/resources/_DSD-hierarchical-data-extension-UUID-v1.pdf>, <URL:http://www.uefi.org/sites/default/files/resources/_DSD-hierarchical-data-extension-UUID-v1.1.pdf>,
referenced 2016-10-04. referenced 2016-10-04.
[6] Advanced Configuration and Power Interface Specification. [6] Advanced Configuration and Power Interface Specification.
......
...@@ -165,7 +165,6 @@ struct acpi_namespace_node { ...@@ -165,7 +165,6 @@ struct acpi_namespace_node {
#define ANOBJ_EVALUATED 0x20 /* Set on first evaluation of node */ #define ANOBJ_EVALUATED 0x20 /* Set on first evaluation of node */
#define ANOBJ_ALLOCATED_BUFFER 0x40 /* Method AML buffer is dynamic (install_method) */ #define ANOBJ_ALLOCATED_BUFFER 0x40 /* Method AML buffer is dynamic (install_method) */
#define IMPLICIT_EXTERNAL 0x02 /* iASL only: This object created implicitly via External */
#define ANOBJ_IS_EXTERNAL 0x08 /* iASL only: This object created via External() */ #define ANOBJ_IS_EXTERNAL 0x08 /* iASL only: This object created via External() */
#define ANOBJ_METHOD_NO_RETVAL 0x10 /* iASL only: Method has no return value */ #define ANOBJ_METHOD_NO_RETVAL 0x10 /* iASL only: Method has no return value */
#define ANOBJ_METHOD_SOME_NO_RETVAL 0x20 /* iASL only: Method has at least one return value */ #define ANOBJ_METHOD_SOME_NO_RETVAL 0x20 /* iASL only: Method has at least one return value */
......
...@@ -613,13 +613,6 @@ acpi_ns_lookup(union acpi_generic_state *scope_info, ...@@ -613,13 +613,6 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
/* Special handling for the last segment (num_segments == 0) */ /* Special handling for the last segment (num_segments == 0) */
else { else {
#ifdef ACPI_ASL_COMPILER
if (!acpi_gbl_disasm_flag
&& (this_node->flags & ANOBJ_IS_EXTERNAL)) {
this_node->flags &= ~IMPLICIT_EXTERNAL;
}
#endif
/* /*
* Sanity typecheck of the target object: * Sanity typecheck of the target object:
* *
......
...@@ -381,7 +381,6 @@ acpi_ns_search_and_enter(u32 target_name, ...@@ -381,7 +381,6 @@ acpi_ns_search_and_enter(u32 target_name,
if (flags & ACPI_NS_EXTERNAL || if (flags & ACPI_NS_EXTERNAL ||
(walk_state && walk_state->opcode == AML_SCOPE_OP)) { (walk_state && walk_state->opcode == AML_SCOPE_OP)) {
new_node->flags |= ANOBJ_IS_EXTERNAL; new_node->flags |= ANOBJ_IS_EXTERNAL;
new_node->flags |= IMPLICIT_EXTERNAL;
} }
#endif #endif
......
...@@ -542,6 +542,23 @@ static int acpi_data_get_property_array(const struct acpi_device_data *data, ...@@ -542,6 +542,23 @@ static int acpi_data_get_property_array(const struct acpi_device_data *data,
return 0; return 0;
} }
static struct fwnode_handle *
acpi_fwnode_get_named_child_node(const struct fwnode_handle *fwnode,
const char *childname)
{
struct fwnode_handle *child;
/*
* Find first matching named child node of this fwnode.
* For ACPI this will be a data only sub-node.
*/
fwnode_for_each_child_node(fwnode, child)
if (acpi_data_node_match(child, childname))
return child;
return NULL;
}
/** /**
* __acpi_node_get_property_reference - returns handle to the referenced object * __acpi_node_get_property_reference - returns handle to the referenced object
* @fwnode: Firmware node to get the property from * @fwnode: Firmware node to get the property from
...@@ -579,7 +596,7 @@ static int acpi_data_get_property_array(const struct acpi_device_data *data, ...@@ -579,7 +596,7 @@ static int acpi_data_get_property_array(const struct acpi_device_data *data,
*/ */
int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode, int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
const char *propname, size_t index, size_t num_args, const char *propname, size_t index, size_t num_args,
struct acpi_reference_args *args) struct fwnode_reference_args *args)
{ {
const union acpi_object *element, *end; const union acpi_object *element, *end;
const union acpi_object *obj; const union acpi_object *obj;
...@@ -607,7 +624,7 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode, ...@@ -607,7 +624,7 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
if (ret) if (ret)
return ret == -ENODEV ? -EINVAL : ret; return ret == -ENODEV ? -EINVAL : ret;
args->adev = device; args->fwnode = acpi_fwnode_handle(device);
args->nargs = 0; args->nargs = 0;
return 0; return 0;
} }
...@@ -633,6 +650,8 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode, ...@@ -633,6 +650,8 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
u32 nargs, i; u32 nargs, i;
if (element->type == ACPI_TYPE_LOCAL_REFERENCE) { if (element->type == ACPI_TYPE_LOCAL_REFERENCE) {
struct fwnode_handle *ref_fwnode;
ret = acpi_bus_get_device(element->reference.handle, ret = acpi_bus_get_device(element->reference.handle,
&device); &device);
if (ret) if (ret)
...@@ -641,6 +660,19 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode, ...@@ -641,6 +660,19 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
nargs = 0; nargs = 0;
element++; element++;
/*
* Find the referred data extension node under the
* referred device node.
*/
for (ref_fwnode = acpi_fwnode_handle(device);
element < end && element->type == ACPI_TYPE_STRING;
element++) {
ref_fwnode = acpi_fwnode_get_named_child_node(
ref_fwnode, element->string.pointer);
if (!ref_fwnode)
return -EINVAL;
}
/* assume following integer elements are all args */ /* assume following integer elements are all args */
for (i = 0; element + i < end && i < num_args; i++) { for (i = 0; element + i < end && i < num_args; i++) {
int type = element[i].type; int type = element[i].type;
...@@ -653,11 +685,11 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode, ...@@ -653,11 +685,11 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
return -EINVAL; return -EINVAL;
} }
if (nargs > MAX_ACPI_REFERENCE_ARGS) if (nargs > NR_FWNODE_REFERENCE_ARGS)
return -EINVAL; return -EINVAL;
if (idx == index) { if (idx == index) {
args->adev = device; args->fwnode = ref_fwnode;
args->nargs = nargs; args->nargs = nargs;
for (i = 0; i < nargs; i++) for (i = 0; i < nargs; i++)
args->args[i] = element[i].integer.value; args->args[i] = element[i].integer.value;
...@@ -995,16 +1027,36 @@ struct fwnode_handle *acpi_node_get_parent(const struct fwnode_handle *fwnode) ...@@ -995,16 +1027,36 @@ struct fwnode_handle *acpi_node_get_parent(const struct fwnode_handle *fwnode)
return NULL; return NULL;
} }
/*
* Return true if the node is an ACPI graph node. Called on either ports
* or endpoints.
*/
static bool is_acpi_graph_node(struct fwnode_handle *fwnode,
const char *str)
{
unsigned int len = strlen(str);
const char *name;
if (!len || !is_acpi_data_node(fwnode))
return false;
name = to_acpi_data_node(fwnode)->name;
return (fwnode_property_present(fwnode, "reg") &&
!strncmp(name, str, len) && name[len] == '@') ||
fwnode_property_present(fwnode, str);
}
/** /**
* acpi_graph_get_next_endpoint - Get next endpoint ACPI firmware node * acpi_graph_get_next_endpoint - Get next endpoint ACPI firmware node
* @fwnode: Pointer to the parent firmware node * @fwnode: Pointer to the parent firmware node
* @prev: Previous endpoint node or %NULL to get the first * @prev: Previous endpoint node or %NULL to get the first
* *
* Looks up next endpoint ACPI firmware node below a given @fwnode. Returns * Looks up next endpoint ACPI firmware node below a given @fwnode. Returns
* %NULL if there is no next endpoint, ERR_PTR() in case of error. In case * %NULL if there is no next endpoint or in case of error. In case of success
* of success the next endpoint is returned. * the next endpoint is returned.
*/ */
struct fwnode_handle *acpi_graph_get_next_endpoint( static struct fwnode_handle *acpi_graph_get_next_endpoint(
const struct fwnode_handle *fwnode, struct fwnode_handle *prev) const struct fwnode_handle *fwnode, struct fwnode_handle *prev)
{ {
struct fwnode_handle *port = NULL; struct fwnode_handle *port = NULL;
...@@ -1013,8 +1065,14 @@ struct fwnode_handle *acpi_graph_get_next_endpoint( ...@@ -1013,8 +1065,14 @@ struct fwnode_handle *acpi_graph_get_next_endpoint(
if (!prev) { if (!prev) {
do { do {
port = fwnode_get_next_child_node(fwnode, port); port = fwnode_get_next_child_node(fwnode, port);
/* Ports must have port property */ /*
if (fwnode_property_present(port, "port")) * The names of the port nodes begin with "port@"
* followed by the number of the port node and they also
* have a "reg" property that also has the number of the
* port node. For compatibility reasons a node is also
* recognised as a port node from the "port" property.
*/
if (is_acpi_graph_node(port, "port"))
break; break;
} while (port); } while (port);
} else { } else {
...@@ -1029,15 +1087,19 @@ struct fwnode_handle *acpi_graph_get_next_endpoint( ...@@ -1029,15 +1087,19 @@ struct fwnode_handle *acpi_graph_get_next_endpoint(
port = fwnode_get_next_child_node(fwnode, port); port = fwnode_get_next_child_node(fwnode, port);
if (!port) if (!port)
break; break;
if (fwnode_property_present(port, "port")) if (is_acpi_graph_node(port, "port"))
endpoint = fwnode_get_next_child_node(port, NULL); endpoint = fwnode_get_next_child_node(port, NULL);
} }
if (endpoint) { /*
/* Endpoints must have "endpoint" property */ * The names of the endpoint nodes begin with "endpoint@" followed by
if (!fwnode_property_present(endpoint, "endpoint")) * the number of the endpoint node and they also have a "reg" property
return ERR_PTR(-EPROTO); * that also has the number of the endpoint node. For compatibility
} * reasons a node is also recognised as an endpoint node from the
* "endpoint" property.
*/
if (!is_acpi_graph_node(endpoint, "endpoint"))
return NULL;
return endpoint; return endpoint;
} }
...@@ -1074,65 +1136,42 @@ static struct fwnode_handle *acpi_graph_get_child_prop_value( ...@@ -1074,65 +1136,42 @@ static struct fwnode_handle *acpi_graph_get_child_prop_value(
/** /**
* acpi_graph_get_remote_enpoint - Parses and returns remote end of an endpoint * acpi_graph_get_remote_enpoint - Parses and returns remote end of an endpoint
* @fwnode: Endpoint firmware node pointing to a remote device * @fwnode: Endpoint firmware node pointing to a remote device
* @parent: Firmware node of remote port parent is filled here if not %NULL
* @port: Firmware node of remote port is filled here if not %NULL
* @endpoint: Firmware node of remote endpoint is filled here if not %NULL * @endpoint: Firmware node of remote endpoint is filled here if not %NULL
* *
* Function parses remote end of ACPI firmware remote endpoint and fills in * Returns the remote endpoint corresponding to @__fwnode. NULL on error.
* fields requested by the caller. Returns %0 in case of success and
* negative errno otherwise.
*/ */
int acpi_graph_get_remote_endpoint(const struct fwnode_handle *__fwnode, static struct fwnode_handle *
struct fwnode_handle **parent, acpi_graph_get_remote_endpoint(const struct fwnode_handle *__fwnode)
struct fwnode_handle **port,
struct fwnode_handle **endpoint)
{ {
struct fwnode_handle *fwnode; struct fwnode_handle *fwnode;
unsigned int port_nr, endpoint_nr; unsigned int port_nr, endpoint_nr;
struct acpi_reference_args args; struct fwnode_reference_args args;
int ret; int ret;
memset(&args, 0, sizeof(args)); memset(&args, 0, sizeof(args));
ret = acpi_node_get_property_reference(__fwnode, "remote-endpoint", 0, ret = acpi_node_get_property_reference(__fwnode, "remote-endpoint", 0,
&args); &args);
if (ret) if (ret)
return ret; return NULL;
/* Direct endpoint reference? */
if (!is_acpi_device_node(args.fwnode))
return args.nargs ? NULL : args.fwnode;
/* /*
* Always require two arguments with the reference: port and * Always require two arguments with the reference: port and
* endpoint indices. * endpoint indices.
*/ */
if (args.nargs != 2) if (args.nargs != 2)
return -EPROTO; return NULL;
fwnode = acpi_fwnode_handle(args.adev); fwnode = args.fwnode;
port_nr = args.args[0]; port_nr = args.args[0];
endpoint_nr = args.args[1]; endpoint_nr = args.args[1];
if (parent)
*parent = fwnode;
if (!port && !endpoint)
return 0;
fwnode = acpi_graph_get_child_prop_value(fwnode, "port", port_nr); fwnode = acpi_graph_get_child_prop_value(fwnode, "port", port_nr);
if (!fwnode)
return -EPROTO;
if (port)
*port = fwnode;
if (!endpoint)
return 0;
fwnode = acpi_graph_get_child_prop_value(fwnode, "endpoint", return acpi_graph_get_child_prop_value(fwnode, "endpoint", endpoint_nr);
endpoint_nr);
if (!fwnode)
return -EPROTO;
*endpoint = fwnode;
return 0;
} }
static bool acpi_fwnode_device_is_available(const struct fwnode_handle *fwnode) static bool acpi_fwnode_device_is_available(const struct fwnode_handle *fwnode)
...@@ -1186,70 +1225,14 @@ acpi_fwnode_property_read_string_array(const struct fwnode_handle *fwnode, ...@@ -1186,70 +1225,14 @@ acpi_fwnode_property_read_string_array(const struct fwnode_handle *fwnode,
val, nval); val, nval);
} }
static struct fwnode_handle *
acpi_fwnode_get_named_child_node(const struct fwnode_handle *fwnode,
const char *childname)
{
struct fwnode_handle *child;
/*
* Find first matching named child node of this fwnode.
* For ACPI this will be a data only sub-node.
*/
fwnode_for_each_child_node(fwnode, child)
if (acpi_data_node_match(child, childname))
return child;
return NULL;
}
static int static int
acpi_fwnode_get_reference_args(const struct fwnode_handle *fwnode, acpi_fwnode_get_reference_args(const struct fwnode_handle *fwnode,
const char *prop, const char *nargs_prop, const char *prop, const char *nargs_prop,
unsigned int args_count, unsigned int index, unsigned int args_count, unsigned int index,
struct fwnode_reference_args *args) struct fwnode_reference_args *args)
{ {
struct acpi_reference_args acpi_args; return __acpi_node_get_property_reference(fwnode, prop, index,
unsigned int i; args_count, args);
int ret;
ret = __acpi_node_get_property_reference(fwnode, prop, index,
args_count, &acpi_args);
if (ret < 0)
return ret;
if (!args)
return 0;
args->nargs = acpi_args.nargs;
args->fwnode = acpi_fwnode_handle(acpi_args.adev);
for (i = 0; i < NR_FWNODE_REFERENCE_ARGS; i++)
args->args[i] = i < acpi_args.nargs ? acpi_args.args[i] : 0;
return 0;
}
static struct fwnode_handle *
acpi_fwnode_graph_get_next_endpoint(const struct fwnode_handle *fwnode,
struct fwnode_handle *prev)
{
struct fwnode_handle *endpoint;
endpoint = acpi_graph_get_next_endpoint(fwnode, prev);
if (IS_ERR(endpoint))
return NULL;
return endpoint;
}
static struct fwnode_handle *
acpi_fwnode_graph_get_remote_endpoint(const struct fwnode_handle *fwnode)
{
struct fwnode_handle *endpoint = NULL;
acpi_graph_get_remote_endpoint(fwnode, NULL, NULL, &endpoint);
return endpoint;
} }
static struct fwnode_handle * static struct fwnode_handle *
...@@ -1265,8 +1248,10 @@ static int acpi_fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode, ...@@ -1265,8 +1248,10 @@ static int acpi_fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode,
endpoint->local_fwnode = fwnode; endpoint->local_fwnode = fwnode;
fwnode_property_read_u32(port_fwnode, "port", &endpoint->port); if (fwnode_property_read_u32(port_fwnode, "reg", &endpoint->port))
fwnode_property_read_u32(fwnode, "endpoint", &endpoint->id); fwnode_property_read_u32(port_fwnode, "port", &endpoint->port);
if (fwnode_property_read_u32(fwnode, "reg", &endpoint->id))
fwnode_property_read_u32(fwnode, "endpoint", &endpoint->id);
return 0; return 0;
} }
...@@ -1292,9 +1277,9 @@ acpi_fwnode_device_get_match_data(const struct fwnode_handle *fwnode, ...@@ -1292,9 +1277,9 @@ acpi_fwnode_device_get_match_data(const struct fwnode_handle *fwnode,
.get_named_child_node = acpi_fwnode_get_named_child_node, \ .get_named_child_node = acpi_fwnode_get_named_child_node, \
.get_reference_args = acpi_fwnode_get_reference_args, \ .get_reference_args = acpi_fwnode_get_reference_args, \
.graph_get_next_endpoint = \ .graph_get_next_endpoint = \
acpi_fwnode_graph_get_next_endpoint, \ acpi_graph_get_next_endpoint, \
.graph_get_remote_endpoint = \ .graph_get_remote_endpoint = \
acpi_fwnode_graph_get_remote_endpoint, \ acpi_graph_get_remote_endpoint, \
.graph_get_port_parent = acpi_fwnode_get_parent, \ .graph_get_port_parent = acpi_fwnode_get_parent, \
.graph_parse_endpoint = acpi_fwnode_graph_parse_endpoint, \ .graph_parse_endpoint = acpi_fwnode_graph_parse_endpoint, \
}; \ }; \
......
...@@ -353,7 +353,7 @@ EXPORT_SYMBOL_GPL(devm_acpi_dev_remove_driver_gpios); ...@@ -353,7 +353,7 @@ EXPORT_SYMBOL_GPL(devm_acpi_dev_remove_driver_gpios);
static bool acpi_get_driver_gpio_data(struct acpi_device *adev, static bool acpi_get_driver_gpio_data(struct acpi_device *adev,
const char *name, int index, const char *name, int index,
struct acpi_reference_args *args, struct fwnode_reference_args *args,
unsigned int *quirks) unsigned int *quirks)
{ {
const struct acpi_gpio_mapping *gm; const struct acpi_gpio_mapping *gm;
...@@ -365,7 +365,7 @@ static bool acpi_get_driver_gpio_data(struct acpi_device *adev, ...@@ -365,7 +365,7 @@ static bool acpi_get_driver_gpio_data(struct acpi_device *adev,
if (!strcmp(name, gm->name) && gm->data && index < gm->size) { if (!strcmp(name, gm->name) && gm->data && index < gm->size) {
const struct acpi_gpio_params *par = gm->data + index; const struct acpi_gpio_params *par = gm->data + index;
args->adev = adev; args->fwnode = acpi_fwnode_handle(adev);
args->args[0] = par->crs_entry_index; args->args[0] = par->crs_entry_index;
args->args[1] = par->line_index; args->args[1] = par->line_index;
args->args[2] = par->active_low; args->args[2] = par->active_low;
...@@ -528,7 +528,7 @@ static int acpi_gpio_property_lookup(struct fwnode_handle *fwnode, ...@@ -528,7 +528,7 @@ static int acpi_gpio_property_lookup(struct fwnode_handle *fwnode,
const char *propname, int index, const char *propname, int index,
struct acpi_gpio_lookup *lookup) struct acpi_gpio_lookup *lookup)
{ {
struct acpi_reference_args args; struct fwnode_reference_args args;
unsigned int quirks = 0; unsigned int quirks = 0;
int ret; int ret;
...@@ -549,6 +549,8 @@ static int acpi_gpio_property_lookup(struct fwnode_handle *fwnode, ...@@ -549,6 +549,8 @@ static int acpi_gpio_property_lookup(struct fwnode_handle *fwnode,
* The property was found and resolved, so need to lookup the GPIO based * The property was found and resolved, so need to lookup the GPIO based
* on returned args. * on returned args.
*/ */
if (!to_acpi_device_node(args.fwnode))
return -EINVAL;
if (args.nargs != 3) if (args.nargs != 3)
return -EPROTO; return -EPROTO;
...@@ -556,8 +558,9 @@ static int acpi_gpio_property_lookup(struct fwnode_handle *fwnode, ...@@ -556,8 +558,9 @@ static int acpi_gpio_property_lookup(struct fwnode_handle *fwnode,
lookup->pin_index = args.args[1]; lookup->pin_index = args.args[1];
lookup->active_low = !!args.args[2]; lookup->active_low = !!args.args[2];
lookup->info.adev = args.adev; lookup->info.adev = to_acpi_device_node(args.fwnode);
lookup->info.quirks = quirks; lookup->info.quirks = quirks;
return 0; return 0;
} }
......
...@@ -1435,7 +1435,7 @@ static int hns_roce_v1_reset(struct hns_roce_dev *hr_dev, bool dereset) ...@@ -1435,7 +1435,7 @@ static int hns_roce_v1_reset(struct hns_roce_dev *hr_dev, bool dereset)
} }
fwnode = &dsaf_node->fwnode; fwnode = &dsaf_node->fwnode;
} else if (is_acpi_device_node(dev->fwnode)) { } else if (is_acpi_device_node(dev->fwnode)) {
struct acpi_reference_args args; struct fwnode_reference_args args;
ret = acpi_node_get_property_reference(dev->fwnode, ret = acpi_node_get_property_reference(dev->fwnode,
"dsaf-handle", 0, &args); "dsaf-handle", 0, &args);
...@@ -1443,7 +1443,7 @@ static int hns_roce_v1_reset(struct hns_roce_dev *hr_dev, bool dereset) ...@@ -1443,7 +1443,7 @@ static int hns_roce_v1_reset(struct hns_roce_dev *hr_dev, bool dereset)
dev_err(dev, "could not find dsaf-handle\n"); dev_err(dev, "could not find dsaf-handle\n");
return ret; return ret;
} }
fwnode = acpi_fwnode_handle(args.adev); fwnode = args.fwnode;
} else { } else {
dev_err(dev, "cannot read data from DT or ACPI\n"); dev_err(dev, "cannot read data from DT or ACPI\n");
return -ENXIO; return -ENXIO;
...@@ -4835,16 +4835,14 @@ static int hns_roce_get_cfg(struct hns_roce_dev *hr_dev) ...@@ -4835,16 +4835,14 @@ static int hns_roce_get_cfg(struct hns_roce_dev *hr_dev)
continue; continue;
pdev = of_find_device_by_node(net_node); pdev = of_find_device_by_node(net_node);
} else if (is_acpi_device_node(dev->fwnode)) { } else if (is_acpi_device_node(dev->fwnode)) {
struct acpi_reference_args args; struct fwnode_reference_args args;
struct fwnode_handle *fwnode;
ret = acpi_node_get_property_reference(dev->fwnode, ret = acpi_node_get_property_reference(dev->fwnode,
"eth-handle", "eth-handle",
i, &args); i, &args);
if (ret) if (ret)
continue; continue;
fwnode = acpi_fwnode_handle(args.adev); pdev = hns_roce_find_pdev(args.fwnode);
pdev = hns_roce_find_pdev(fwnode);
} else { } else {
dev_err(dev, "cannot read data from DT or ACPI\n"); dev_err(dev, "cannot read data from DT or ACPI\n");
return -ENXIO; return -ENXIO;
......
...@@ -739,7 +739,7 @@ static struct fwnode_handle *v4l2_fwnode_reference_get_int_prop( ...@@ -739,7 +739,7 @@ static struct fwnode_handle *v4l2_fwnode_reference_get_int_prop(
const char * const *props, unsigned int nprops) const char * const *props, unsigned int nprops)
{ {
struct fwnode_reference_args fwnode_args; struct fwnode_reference_args fwnode_args;
unsigned int *args = fwnode_args.args; u64 *args = fwnode_args.args;
struct fwnode_handle *child; struct fwnode_handle *child;
int ret; int ret;
......
...@@ -836,19 +836,19 @@ static void xgene_enet_adjust_link(struct net_device *ndev) ...@@ -836,19 +836,19 @@ static void xgene_enet_adjust_link(struct net_device *ndev)
#ifdef CONFIG_ACPI #ifdef CONFIG_ACPI
static struct acpi_device *acpi_phy_find_device(struct device *dev) static struct acpi_device *acpi_phy_find_device(struct device *dev)
{ {
struct acpi_reference_args args; struct fwnode_reference_args args;
struct fwnode_handle *fw_node; struct fwnode_handle *fw_node;
int status; int status;
fw_node = acpi_fwnode_handle(ACPI_COMPANION(dev)); fw_node = acpi_fwnode_handle(ACPI_COMPANION(dev));
status = acpi_node_get_property_reference(fw_node, "phy-handle", 0, status = acpi_node_get_property_reference(fw_node, "phy-handle", 0,
&args); &args);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status) || !is_acpi_device_node(args.fwnode)) {
dev_dbg(dev, "No matching phy in ACPI table\n"); dev_dbg(dev, "No matching phy in ACPI table\n");
return NULL; return NULL;
} }
return args.adev; return to_acpi_device_node(args.fwnode);
} }
#endif #endif
......
...@@ -708,7 +708,7 @@ hns_mac_register_phydev(struct mii_bus *mdio, struct hns_mac_cb *mac_cb, ...@@ -708,7 +708,7 @@ hns_mac_register_phydev(struct mii_bus *mdio, struct hns_mac_cb *mac_cb,
static int hns_mac_register_phy(struct hns_mac_cb *mac_cb) static int hns_mac_register_phy(struct hns_mac_cb *mac_cb)
{ {
struct acpi_reference_args args; struct fwnode_reference_args args;
struct platform_device *pdev; struct platform_device *pdev;
struct mii_bus *mii_bus; struct mii_bus *mii_bus;
int rc; int rc;
...@@ -722,13 +722,15 @@ static int hns_mac_register_phy(struct hns_mac_cb *mac_cb) ...@@ -722,13 +722,15 @@ static int hns_mac_register_phy(struct hns_mac_cb *mac_cb)
mac_cb->fw_port, "mdio-node", 0, &args); mac_cb->fw_port, "mdio-node", 0, &args);
if (rc) if (rc)
return rc; return rc;
if (!is_acpi_device_node(args.fwnode))
return -EINVAL;
addr = hns_mac_phy_parse_addr(mac_cb->dev, mac_cb->fw_port); addr = hns_mac_phy_parse_addr(mac_cb->dev, mac_cb->fw_port);
if (addr < 0) if (addr < 0)
return addr; return addr;
/* dev address in adev */ /* dev address in adev */
pdev = hns_dsaf_find_platform_device(acpi_fwnode_handle(args.adev)); pdev = hns_dsaf_find_platform_device(args.fwnode);
if (!pdev) { if (!pdev) {
dev_err(mac_cb->dev, "mac%d mdio pdev is NULL\n", dev_err(mac_cb->dev, "mac%d mdio pdev is NULL\n",
mac_cb->mac_id); mac_cb->mac_id);
......
...@@ -2377,7 +2377,7 @@ static int hns_nic_dev_probe(struct platform_device *pdev) ...@@ -2377,7 +2377,7 @@ static int hns_nic_dev_probe(struct platform_device *pdev)
} }
priv->fwnode = &ae_node->fwnode; priv->fwnode = &ae_node->fwnode;
} else if (is_acpi_node(dev->fwnode)) { } else if (is_acpi_node(dev->fwnode)) {
struct acpi_reference_args args; struct fwnode_reference_args args;
if (acpi_dev_found(hns_enet_acpi_match[0].id)) if (acpi_dev_found(hns_enet_acpi_match[0].id))
priv->enet_ver = AE_VERSION_1; priv->enet_ver = AE_VERSION_1;
...@@ -2393,7 +2393,11 @@ static int hns_nic_dev_probe(struct platform_device *pdev) ...@@ -2393,7 +2393,11 @@ static int hns_nic_dev_probe(struct platform_device *pdev)
dev_err(dev, "not find ae-handle\n"); dev_err(dev, "not find ae-handle\n");
goto out_read_prop_fail; goto out_read_prop_fail;
} }
priv->fwnode = acpi_fwnode_handle(args.adev); if (!is_acpi_device_node(args.fwnode)) {
ret = -EINVAL;
goto out_read_prop_fail;
}
priv->fwnode = args.fwnode;
} else { } else {
dev_err(dev, "cannot read cfg data from OF or acpi\n"); dev_err(dev, "cannot read cfg data from OF or acpi\n");
return -ENXIO; return -ENXIO;
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
/* Current ACPICA subsystem version in YYYYMMDD format */ /* Current ACPICA subsystem version in YYYYMMDD format */
#define ACPI_CA_VERSION 0x20180531 #define ACPI_CA_VERSION 0x20180629
#include <acpi/acconfig.h> #include <acpi/acconfig.h>
#include <acpi/actypes.h> #include <acpi/actypes.h>
......
...@@ -1058,27 +1058,20 @@ static inline int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index) ...@@ -1058,27 +1058,20 @@ static inline int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index)
/* Device properties */ /* Device properties */
#define MAX_ACPI_REFERENCE_ARGS 8
struct acpi_reference_args {
struct acpi_device *adev;
size_t nargs;
u64 args[MAX_ACPI_REFERENCE_ARGS];
};
#ifdef CONFIG_ACPI #ifdef CONFIG_ACPI
int acpi_dev_get_property(const struct acpi_device *adev, const char *name, int acpi_dev_get_property(const struct acpi_device *adev, const char *name,
acpi_object_type type, const union acpi_object **obj); acpi_object_type type, const union acpi_object **obj);
int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode, int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
const char *name, size_t index, size_t num_args, const char *name, size_t index, size_t num_args,
struct acpi_reference_args *args); struct fwnode_reference_args *args);
static inline int acpi_node_get_property_reference( static inline int acpi_node_get_property_reference(
const struct fwnode_handle *fwnode, const struct fwnode_handle *fwnode,
const char *name, size_t index, const char *name, size_t index,
struct acpi_reference_args *args) struct fwnode_reference_args *args)
{ {
return __acpi_node_get_property_reference(fwnode, name, index, return __acpi_node_get_property_reference(fwnode, name, index,
MAX_ACPI_REFERENCE_ARGS, args); NR_FWNODE_REFERENCE_ARGS, args);
} }
int acpi_node_prop_get(const struct fwnode_handle *fwnode, const char *propname, int acpi_node_prop_get(const struct fwnode_handle *fwnode, const char *propname,
...@@ -1096,14 +1089,6 @@ struct fwnode_handle *acpi_get_next_subnode(const struct fwnode_handle *fwnode, ...@@ -1096,14 +1089,6 @@ struct fwnode_handle *acpi_get_next_subnode(const struct fwnode_handle *fwnode,
struct fwnode_handle *child); struct fwnode_handle *child);
struct fwnode_handle *acpi_node_get_parent(const struct fwnode_handle *fwnode); struct fwnode_handle *acpi_node_get_parent(const struct fwnode_handle *fwnode);
struct fwnode_handle *
acpi_graph_get_next_endpoint(const struct fwnode_handle *fwnode,
struct fwnode_handle *prev);
int acpi_graph_get_remote_endpoint(const struct fwnode_handle *fwnode,
struct fwnode_handle **remote,
struct fwnode_handle **port,
struct fwnode_handle **endpoint);
struct acpi_probe_entry; struct acpi_probe_entry;
typedef bool (*acpi_probe_entry_validate_subtbl)(struct acpi_subtable_header *, typedef bool (*acpi_probe_entry_validate_subtbl)(struct acpi_subtable_header *,
struct acpi_probe_entry *); struct acpi_probe_entry *);
...@@ -1169,7 +1154,7 @@ static inline int acpi_dev_get_property(struct acpi_device *adev, ...@@ -1169,7 +1154,7 @@ static inline int acpi_dev_get_property(struct acpi_device *adev,
static inline int static inline int
__acpi_node_get_property_reference(const struct fwnode_handle *fwnode, __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
const char *name, size_t index, size_t num_args, const char *name, size_t index, size_t num_args,
struct acpi_reference_args *args) struct fwnode_reference_args *args)
{ {
return -ENXIO; return -ENXIO;
} }
...@@ -1177,7 +1162,7 @@ __acpi_node_get_property_reference(const struct fwnode_handle *fwnode, ...@@ -1177,7 +1162,7 @@ __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
static inline int static inline int
acpi_node_get_property_reference(const struct fwnode_handle *fwnode, acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
const char *name, size_t index, const char *name, size_t index,
struct acpi_reference_args *args) struct fwnode_reference_args *args)
{ {
return -ENXIO; return -ENXIO;
} }
......
...@@ -45,7 +45,7 @@ struct fwnode_endpoint { ...@@ -45,7 +45,7 @@ struct fwnode_endpoint {
struct fwnode_reference_args { struct fwnode_reference_args {
struct fwnode_handle *fwnode; struct fwnode_handle *fwnode;
unsigned int nargs; unsigned int nargs;
unsigned int args[NR_FWNODE_REFERENCE_ARGS]; u64 args[NR_FWNODE_REFERENCE_ARGS];
}; };
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment