Skip to content

Commit

Permalink
Merge branches 'device-properties' and 'acpi-misc'
Browse files Browse the repository at this point in the history
* device-properties:
  ACPI / property: Allow holes in reference properties

* acpi-misc:
  MAINTAINERS: Add ARM64-specific ACPI maintainers entry
  • Loading branch information
rafaeljw committed Oct 14, 2016
3 parents 72d3992 + b60e4ea + daeb201 commit 3f62d52
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 52 deletions.
8 changes: 8 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,14 @@ W: https://01.org/linux-acpi
S: Supported
F: drivers/acpi/fan.c

ACPI FOR ARM64 (ACPI/arm64)
M: Lorenzo Pieralisi <[email protected]>
M: Hanjun Guo <[email protected]>
M: Sudeep Holla <[email protected]>
L: [email protected]
S: Maintained
F: drivers/acpi/arm64

ACPI THERMAL DRIVER
M: Zhang Rui <[email protected]>
L: [email protected]
Expand Down
117 changes: 68 additions & 49 deletions drivers/acpi/property.c
Original file line number Diff line number Diff line change
Expand Up @@ -468,10 +468,11 @@ static int acpi_data_get_property_array(struct acpi_device_data *data,
}

/**
* acpi_data_get_property_reference - returns handle to the referenced object
* @data: ACPI device data object containing the property
* __acpi_node_get_property_reference - returns handle to the referenced object
* @fwnode: Firmware node to get the property from
* @propname: Name of the property
* @index: Index of the reference to return
* @num_args: Maximum number of arguments after each reference
* @args: Location to store the returned reference with optional arguments
*
* Find property with @name, verifify that it is a package containing at least
Expand All @@ -482,17 +483,40 @@ static int acpi_data_get_property_array(struct acpi_device_data *data,
* If there's more than one reference in the property value package, @index is
* used to select the one to return.
*
* It is possible to leave holes in the property value set like in the
* example below:
*
* Package () {
* "cs-gpios",
* Package () {
* ^GPIO, 19, 0, 0,
* ^GPIO, 20, 0, 0,
* 0,
* ^GPIO, 21, 0, 0,
* }
* }
*
* Calling this function with index %2 return %-ENOENT and with index %3
* returns the last entry. If the property does not contain any more values
* %-ENODATA is returned. The NULL entry must be single integer and
* preferably contain value %0.
*
* Return: %0 on success, negative error code on failure.
*/
static int acpi_data_get_property_reference(struct acpi_device_data *data,
const char *propname, size_t index,
struct acpi_reference_args *args)
int __acpi_node_get_property_reference(struct fwnode_handle *fwnode,
const char *propname, size_t index, size_t num_args,
struct acpi_reference_args *args)
{
const union acpi_object *element, *end;
const union acpi_object *obj;
struct acpi_device_data *data;
struct acpi_device *device;
int ret, idx = 0;

data = acpi_device_data_of_node(fwnode);
if (!data)
return -EINVAL;

ret = acpi_data_get_property(data, propname, ACPI_TYPE_ANY, &obj);
if (ret)
return ret;
Expand Down Expand Up @@ -532,59 +556,54 @@ static int acpi_data_get_property_reference(struct acpi_device_data *data,
while (element < end) {
u32 nargs, i;

if (element->type != ACPI_TYPE_LOCAL_REFERENCE)
return -EPROTO;

ret = acpi_bus_get_device(element->reference.handle, &device);
if (ret)
return -ENODEV;

element++;
nargs = 0;

/* assume following integer elements are all args */
for (i = 0; element + i < end; i++) {
int type = element[i].type;
if (element->type == ACPI_TYPE_LOCAL_REFERENCE) {
ret = acpi_bus_get_device(element->reference.handle,
&device);
if (ret)
return -ENODEV;

nargs = 0;
element++;

/* assume following integer elements are all args */
for (i = 0; element + i < end && i < num_args; i++) {
int type = element[i].type;

if (type == ACPI_TYPE_INTEGER)
nargs++;
else if (type == ACPI_TYPE_LOCAL_REFERENCE)
break;
else
return -EPROTO;
}

if (type == ACPI_TYPE_INTEGER)
nargs++;
else if (type == ACPI_TYPE_LOCAL_REFERENCE)
break;
else
if (nargs > MAX_ACPI_REFERENCE_ARGS)
return -EPROTO;
}

if (idx++ == index) {
args->adev = device;
args->nargs = nargs;
for (i = 0; i < nargs; i++)
args->args[i] = element[i].integer.value;
if (idx == index) {
args->adev = device;
args->nargs = nargs;
for (i = 0; i < nargs; i++)
args->args[i] = element[i].integer.value;

return 0;
return 0;
}

element += nargs;
} else if (element->type == ACPI_TYPE_INTEGER) {
if (idx == index)
return -ENOENT;
element++;
} else {
return -EPROTO;
}

element += nargs;
idx++;
}

return -EPROTO;
}

/**
* acpi_node_get_property_reference - get a handle to the referenced object.
* @fwnode: Firmware node to get the property from.
* @propname: Name of the property.
* @index: Index of the reference to return.
* @args: Location to store the returned reference with optional arguments.
*/
int acpi_node_get_property_reference(struct fwnode_handle *fwnode,
const char *name, size_t index,
struct acpi_reference_args *args)
{
struct acpi_device_data *data = acpi_device_data_of_node(fwnode);

return data ? acpi_data_get_property_reference(data, name, index, args) : -EINVAL;
return -ENODATA;
}
EXPORT_SYMBOL_GPL(acpi_node_get_property_reference);
EXPORT_SYMBOL_GPL(__acpi_node_get_property_reference);

static int acpi_data_prop_read_single(struct acpi_device_data *data,
const char *propname,
Expand Down
22 changes: 19 additions & 3 deletions include/linux/acpi.h
Original file line number Diff line number Diff line change
Expand Up @@ -934,9 +934,17 @@ struct acpi_reference_args {
#ifdef CONFIG_ACPI
int acpi_dev_get_property(struct acpi_device *adev, const char *name,
acpi_object_type type, const union acpi_object **obj);
int acpi_node_get_property_reference(struct fwnode_handle *fwnode,
const char *name, size_t index,
struct acpi_reference_args *args);
int __acpi_node_get_property_reference(struct fwnode_handle *fwnode,
const char *name, size_t index, size_t num_args,
struct acpi_reference_args *args);

static inline int acpi_node_get_property_reference(struct fwnode_handle *fwnode,
const char *name, size_t index,
struct acpi_reference_args *args)
{
return __acpi_node_get_property_reference(fwnode, name, index,
MAX_ACPI_REFERENCE_ARGS, args);
}

int acpi_node_prop_get(struct fwnode_handle *fwnode, const char *propname,
void **valptr);
Expand Down Expand Up @@ -1012,6 +1020,14 @@ static inline int acpi_dev_get_property(struct acpi_device *adev,
return -ENXIO;
}

static inline int
__acpi_node_get_property_reference(struct fwnode_handle *fwnode,
const char *name, size_t index, size_t num_args,
struct acpi_reference_args *args)
{
return -ENXIO;
}

static inline int acpi_node_get_property_reference(struct fwnode_handle *fwnode,
const char *name, size_t index,
struct acpi_reference_args *args)
Expand Down

0 comments on commit 3f62d52

Please sign in to comment.