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
This commit is contained in:
Rafael J. Wysocki
2018-08-14 10:04:59 +02:00
15 changed files with 258 additions and 189 deletions

View File

@@ -165,7 +165,6 @@ struct acpi_namespace_node {
#define ANOBJ_EVALUATED 0x20 /* Set on first evaluation of node */
#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_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 */

View File

@@ -613,13 +613,6 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
/* Special handling for the last segment (num_segments == 0) */
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:
*

View File

@@ -381,7 +381,6 @@ acpi_ns_search_and_enter(u32 target_name,
if (flags & ACPI_NS_EXTERNAL ||
(walk_state && walk_state->opcode == AML_SCOPE_OP)) {
new_node->flags |= ANOBJ_IS_EXTERNAL;
new_node->flags |= IMPLICIT_EXTERNAL;
}
#endif

View File

@@ -542,6 +542,23 @@ static int acpi_data_get_property_array(const struct acpi_device_data *data,
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
* @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,
*/
int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
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 *obj;
@@ -607,7 +624,7 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
if (ret)
return ret == -ENODEV ? -EINVAL : ret;
args->adev = device;
args->fwnode = acpi_fwnode_handle(device);
args->nargs = 0;
return 0;
}
@@ -633,6 +650,8 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
u32 nargs, i;
if (element->type == ACPI_TYPE_LOCAL_REFERENCE) {
struct fwnode_handle *ref_fwnode;
ret = acpi_bus_get_device(element->reference.handle,
&device);
if (ret)
@@ -641,6 +660,19 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
nargs = 0;
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 */
for (i = 0; element + i < end && i < num_args; i++) {
int type = element[i].type;
@@ -653,11 +685,11 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
return -EINVAL;
}
if (nargs > MAX_ACPI_REFERENCE_ARGS)
if (nargs > NR_FWNODE_REFERENCE_ARGS)
return -EINVAL;
if (idx == index) {
args->adev = device;
args->fwnode = ref_fwnode;
args->nargs = nargs;
for (i = 0; i < nargs; i++)
args->args[i] = element[i].integer.value;
@@ -995,16 +1027,36 @@ struct fwnode_handle *acpi_node_get_parent(const struct fwnode_handle *fwnode)
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
* @fwnode: Pointer to the parent firmware node
* @prev: Previous endpoint node or %NULL to get the first
*
* 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
* of success the next endpoint is returned.
* %NULL if there is no next endpoint or in case of error. In case of success
* 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)
{
struct fwnode_handle *port = NULL;
@@ -1013,8 +1065,14 @@ struct fwnode_handle *acpi_graph_get_next_endpoint(
if (!prev) {
do {
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;
} while (port);
} else {
@@ -1029,15 +1087,19 @@ struct fwnode_handle *acpi_graph_get_next_endpoint(
port = fwnode_get_next_child_node(fwnode, port);
if (!port)
break;
if (fwnode_property_present(port, "port"))
if (is_acpi_graph_node(port, "port"))
endpoint = fwnode_get_next_child_node(port, NULL);
}
if (endpoint) {
/* Endpoints must have "endpoint" property */
if (!fwnode_property_present(endpoint, "endpoint"))
return ERR_PTR(-EPROTO);
}
/*
* The names of the endpoint nodes begin with "endpoint@" followed by
* the number of the endpoint node and they also have a "reg" property
* 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;
}
@@ -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
* @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
*
* Function parses remote end of ACPI firmware remote endpoint and fills in
* fields requested by the caller. Returns %0 in case of success and
* negative errno otherwise.
* Returns the remote endpoint corresponding to @__fwnode. NULL on error.
*/
int acpi_graph_get_remote_endpoint(const struct fwnode_handle *__fwnode,
struct fwnode_handle **parent,
struct fwnode_handle **port,
struct fwnode_handle **endpoint)
static struct fwnode_handle *
acpi_graph_get_remote_endpoint(const struct fwnode_handle *__fwnode)
{
struct fwnode_handle *fwnode;
unsigned int port_nr, endpoint_nr;
struct acpi_reference_args args;
struct fwnode_reference_args args;
int ret;
memset(&args, 0, sizeof(args));
ret = acpi_node_get_property_reference(__fwnode, "remote-endpoint", 0,
&args);
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
* endpoint indices.
*/
if (args.nargs != 2)
return -EPROTO;
return NULL;
fwnode = acpi_fwnode_handle(args.adev);
fwnode = args.fwnode;
port_nr = args.args[0];
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);
if (!fwnode)
return -EPROTO;
if (port)
*port = fwnode;
if (!endpoint)
return 0;
fwnode = acpi_graph_get_child_prop_value(fwnode, "endpoint",
endpoint_nr);
if (!fwnode)
return -EPROTO;
*endpoint = fwnode;
return 0;
return acpi_graph_get_child_prop_value(fwnode, "endpoint", endpoint_nr);
}
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,
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
acpi_fwnode_get_reference_args(const struct fwnode_handle *fwnode,
const char *prop, const char *nargs_prop,
unsigned int args_count, unsigned int index,
struct fwnode_reference_args *args)
{
struct acpi_reference_args acpi_args;
unsigned int i;
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;
return __acpi_node_get_property_reference(fwnode, prop, index,
args_count, args);
}
static struct fwnode_handle *
@@ -1265,8 +1248,10 @@ static int acpi_fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode,
endpoint->local_fwnode = fwnode;
fwnode_property_read_u32(port_fwnode, "port", &endpoint->port);
fwnode_property_read_u32(fwnode, "endpoint", &endpoint->id);
if (fwnode_property_read_u32(port_fwnode, "reg", &endpoint->port))
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;
}
@@ -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_reference_args = acpi_fwnode_get_reference_args, \
.graph_get_next_endpoint = \
acpi_fwnode_graph_get_next_endpoint, \
acpi_graph_get_next_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_parse_endpoint = acpi_fwnode_graph_parse_endpoint, \
}; \