Skip to content

Commit

Permalink
Merge tag 'devprop-4.14-rc5' of git://git.kernel.org/pub/scm/linux/ke…
Browse files Browse the repository at this point in the history
…rnel/git/rafael/linux-pm

Pull device properties framework fixes from Rafael Wysocki:
 "These fix an issue related to device removal introduced during the 4.9
  cycle and fix up new functionality added recently.

  Specifics:

   - Fix a device properties management issue, introduced during the 4.9
     cycle, that causes device properties associated with a parent
     device to go away on a removal of its child in some cases (Jarkko
     Nikula).

   - Fix inconsistencies in error codes returned by a new function
     helper in the device properties framework depending on the
     underlying low-level firmware interface, DT or ACPI, by making the
     meaning of error codes returned in the ACPI case agree with the
     meaning of DT error codes in analogous situations (Sakari Ailus)"

* tag 'devprop-4.14-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  ACPI: properties: Fix __acpi_node_get_property_reference() return codes
  ACPI: properties: Align return codes of __acpi_node_get_property_reference()
  device property: Track owner device of device property
  • Loading branch information
torvalds committed Oct 13, 2017
2 parents 8ff0b97 + 51858a2 commit 3d78827
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 20 deletions.
29 changes: 15 additions & 14 deletions drivers/acpi/property.c
Original file line number Diff line number Diff line change
Expand Up @@ -571,10 +571,9 @@ static int acpi_data_get_property_array(const struct acpi_device_data *data,
* }
* }
*
* 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.
* Calling this function with index %2 or index %3 return %-ENOENT. If the
* property does not contain any more values %-ENOENT is returned. The NULL
* entry must be single integer and preferably contain value %0.
*
* Return: %0 on success, negative error code on failure.
*/
Expand All @@ -590,11 +589,11 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,

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

ret = acpi_data_get_property(data, propname, ACPI_TYPE_ANY, &obj);
if (ret)
return ret;
return ret == -EINVAL ? -ENOENT : -EINVAL;

/*
* The simplest case is when the value is a single reference. Just
Expand All @@ -606,7 +605,7 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,

ret = acpi_bus_get_device(obj->reference.handle, &device);
if (ret)
return ret;
return ret == -ENODEV ? -EINVAL : ret;

args->adev = device;
args->nargs = 0;
Expand All @@ -622,8 +621,10 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
* The index argument is then used to determine which reference
* the caller wants (along with the arguments).
*/
if (obj->type != ACPI_TYPE_PACKAGE || index >= obj->package.count)
return -EPROTO;
if (obj->type != ACPI_TYPE_PACKAGE)
return -EINVAL;
if (index >= obj->package.count)
return -ENOENT;

element = obj->package.elements;
end = element + obj->package.count;
Expand All @@ -635,7 +636,7 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
ret = acpi_bus_get_device(element->reference.handle,
&device);
if (ret)
return -ENODEV;
return -EINVAL;

nargs = 0;
element++;
Expand All @@ -649,11 +650,11 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
else if (type == ACPI_TYPE_LOCAL_REFERENCE)
break;
else
return -EPROTO;
return -EINVAL;
}

if (nargs > MAX_ACPI_REFERENCE_ARGS)
return -EPROTO;
return -EINVAL;

if (idx == index) {
args->adev = device;
Expand All @@ -670,13 +671,13 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode,
return -ENOENT;
element++;
} else {
return -EPROTO;
return -EINVAL;
}

idx++;
}

return -ENODATA;
return -ENOENT;
}
EXPORT_SYMBOL_GPL(__acpi_node_get_property_reference);

Expand Down
19 changes: 13 additions & 6 deletions drivers/base/property.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <linux/phy.h>

struct property_set {
struct device *dev;
struct fwnode_handle fwnode;
const struct property_entry *properties;
};
Expand Down Expand Up @@ -682,6 +683,10 @@ EXPORT_SYMBOL_GPL(fwnode_property_match_string);
* Caller is responsible to call fwnode_handle_put() on the returned
* args->fwnode pointer.
*
* Returns: %0 on success
* %-ENOENT when the index is out of bounds, the index has an empty
* reference or the property was not found
* %-EINVAL on parse error
*/
int fwnode_property_get_reference_args(const struct fwnode_handle *fwnode,
const char *prop, const char *nargs_prop,
Expand Down Expand Up @@ -891,6 +896,7 @@ static struct property_set *pset_copy_set(const struct property_set *pset)
void device_remove_properties(struct device *dev)
{
struct fwnode_handle *fwnode;
struct property_set *pset;

fwnode = dev_fwnode(dev);
if (!fwnode)
Expand All @@ -900,16 +906,16 @@ void device_remove_properties(struct device *dev)
* the pset. If there is no real firmware node (ACPI/DT) primary
* will hold the pset.
*/
if (is_pset_node(fwnode)) {
pset = to_pset_node(fwnode);
if (pset) {
set_primary_fwnode(dev, NULL);
pset_free_set(to_pset_node(fwnode));
} else {
fwnode = fwnode->secondary;
if (!IS_ERR(fwnode) && is_pset_node(fwnode)) {
pset = to_pset_node(fwnode->secondary);
if (pset && dev == pset->dev)
set_secondary_fwnode(dev, NULL);
pset_free_set(to_pset_node(fwnode));
}
}
if (pset && dev == pset->dev)
pset_free_set(pset);
}
EXPORT_SYMBOL_GPL(device_remove_properties);

Expand Down Expand Up @@ -938,6 +944,7 @@ int device_add_properties(struct device *dev,

p->fwnode.ops = &pset_fwnode_ops;
set_secondary_fwnode(dev, &p->fwnode);
p->dev = dev;
return 0;
}
EXPORT_SYMBOL_GPL(device_add_properties);
Expand Down

0 comments on commit 3d78827

Please sign in to comment.