Device properties framework updates for 5.2-rc1

- Fix the handling of data nodes in the ACPI properties support
    code for devices with child devices and hierarchical _DSD
    properties (Pierre-Louis Bossart).
 
  - Add fwnode_graph_get_endpoint_by_id() helper for endpoint lookup
    in device property graphs (Sakari Ailus).
 
  - Restore the _DSD data subnodes GUID comment inadvertently removed
    by one of previous changes (Shunyong Yang).
 -----BEGIN PGP SIGNATURE-----
 
 iQJGBAABCAAwFiEE4fcc61cGeeHD/fCwgsRv/nhiVHEFAlzQE80SHHJqd0Byand5
 c29ja2kubmV0AAoJEILEb/54YlRxWhYP/1WzJY4g5SewgzIW3aRfWBCVrDcysMQ6
 ywVf/aEWxoOTDihJfCcfnzOq0qabQfb9aTH9P5CdP42YQejqZpEb98kOP5Q4Q3Gv
 8wnOMVuOUKrUQK47cgs7VF0tiY0eWpH9YddxN9S3YrmeWGEL8A50mAnYZ0qgl4MR
 EgkAtc3c7QKWMensDJp4udOeFLEor/8MExMOMDzpGIB30j6bXgSkGx2DUvkclCKn
 4YNc664Z0msRNDb6H5Zaf8Bpv6M6zyKq+kuzkJ2FlGRo0FEURpMmSPVw+resrpWq
 9fl3mIGc1rVdlALr28Q9s3QJa/ajinHA+EfcKh1JlFOf2Nnp1l+pWPrUnFoZKm7o
 CtoC+akKfm3EeR5ObjX51yntCYUk14fQ5xMXb8ipsNn/Iou+bqcHxtgQJUnajSnK
 ugHr+xIVounWUWUvhwn8pf+hdQHkUOqfUYz+AOSFdA7UQX1JIepsnup6Wzy+PN+l
 /z/NShcYDWXYoeJjiskjAMtUIoY/cbSDX52MsxnECyIIL6dH/COt3tHOo8Ixr/uY
 q5Zl2Rp7zzPQMmUvZcJcweqdYz23JQGw4fssO8/kM3QXnyt7WD9mSyGeAa6VUw+D
 AAC2gU1YsbcDQopIlo1EZJ/8Lmx08ZX8Jq4jSRfystz98YgOpz2VZpE5QuGdUBze
 lm7wzOwMem5j
 =n6Oe
 -----END PGP SIGNATURE-----

Merge tag 'devprop-5.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull device properties framework updates from Rafael Wysocki:
 "These fix the handling of data nodes in the ACPI properties support
  code, add a new helper for endpoint lookup in property graphs and
  restore a comment inadvertently removed by one of previous changes.

  Specifics:

   - Fix the handling of data nodes in the ACPI properties support code
     for devices with child devices and hierarchical _DSD properties
     (Pierre-Louis Bossart).

   - Add fwnode_graph_get_endpoint_by_id() helper for endpoint lookup in
     device property graphs (Sakari Ailus).

   - Restore the _DSD data subnodes GUID comment inadvertently removed
     by one of previous changes (Shunyong Yang)"

* tag 'devprop-5.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  ACPI / property: fix handling of data_nodes in acpi_get_next_subnode()
  device property: Add fwnode_graph_get_endpoint_by_id()
  ACPI: property: restore _DSD data subnodes GUID comment
This commit is contained in:
Linus Torvalds 2019-05-06 19:45:37 -07:00
commit 4dd2ab9a0f
3 changed files with 102 additions and 0 deletions

View file

@ -44,6 +44,7 @@ static const guid_t prp_guids[] = {
0xbf, 0xf0, 0x76, 0x14, 0x38, 0x07, 0xc3, 0x89),
};
/* ACPI _DSD data subnodes GUID: dbb8e3e6-5886-4ba6-8795-1319f52a966b */
static const guid_t ads_guid =
GUID_INIT(0xdbb8e3e6, 0x5886, 0x4ba6,
0x87, 0x95, 0x13, 0x19, 0xf5, 0x2a, 0x96, 0x6b);
@ -1031,6 +1032,14 @@ struct fwnode_handle *acpi_get_next_subnode(const struct fwnode_handle *fwnode,
const struct acpi_data_node *data = to_acpi_data_node(fwnode);
struct acpi_data_node *dn;
/*
* We can have a combination of device and data nodes, e.g. with
* hierarchical _DSD properties. Make sure the adev pointer is
* restored before going through data nodes, otherwise we will
* be looking for data_nodes below the last device found instead
* of the common fwnode shared by device_nodes and data_nodes.
*/
adev = to_acpi_device_node(fwnode);
if (adev)
head = &adev->data.subnodes;
else if (data)

View file

@ -983,6 +983,81 @@ fwnode_graph_get_remote_node(const struct fwnode_handle *fwnode, u32 port_id,
}
EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_node);
/**
* fwnode_graph_get_endpoint_by_id - get endpoint by port and endpoint numbers
* @fwnode: parent fwnode_handle containing the graph
* @port: identifier of the port node
* @endpoint: identifier of the endpoint node under the port node
* @flags: fwnode lookup flags
*
* Return the fwnode handle of the local endpoint corresponding the port and
* endpoint IDs or NULL if not found.
*
* If FWNODE_GRAPH_ENDPOINT_NEXT is passed in @flags and the specified endpoint
* has not been found, look for the closest endpoint ID greater than the
* specified one and return the endpoint that corresponds to it, if present.
*
* Do not return endpoints that belong to disabled devices, unless
* FWNODE_GRAPH_DEVICE_DISABLED is passed in @flags.
*
* The returned endpoint needs to be released by calling fwnode_handle_put() on
* it when it is not needed any more.
*/
struct fwnode_handle *
fwnode_graph_get_endpoint_by_id(const struct fwnode_handle *fwnode,
u32 port, u32 endpoint, unsigned long flags)
{
struct fwnode_handle *ep = NULL, *best_ep = NULL;
unsigned int best_ep_id = 0;
bool endpoint_next = flags & FWNODE_GRAPH_ENDPOINT_NEXT;
bool enabled_only = !(flags & FWNODE_GRAPH_DEVICE_DISABLED);
while ((ep = fwnode_graph_get_next_endpoint(fwnode, ep))) {
struct fwnode_endpoint fwnode_ep = { 0 };
int ret;
if (enabled_only) {
struct fwnode_handle *dev_node;
bool available;
dev_node = fwnode_graph_get_remote_port_parent(ep);
available = fwnode_device_is_available(dev_node);
fwnode_handle_put(dev_node);
if (!available)
continue;
}
ret = fwnode_graph_parse_endpoint(ep, &fwnode_ep);
if (ret < 0)
continue;
if (fwnode_ep.port != port)
continue;
if (fwnode_ep.id == endpoint)
return ep;
if (!endpoint_next)
continue;
/*
* If the endpoint that has just been found is not the first
* matching one and the ID of the one found previously is closer
* to the requested endpoint ID, skip it.
*/
if (fwnode_ep.id < endpoint ||
(best_ep && best_ep_id < fwnode_ep.id))
continue;
fwnode_handle_put(best_ep);
best_ep = fwnode_handle_get(ep);
best_ep_id = fwnode_ep.id;
}
return best_ep;
}
EXPORT_SYMBOL_GPL(fwnode_graph_get_endpoint_by_id);
/**
* fwnode_graph_parse_endpoint - parse common endpoint node properties
* @fwnode: pointer to endpoint fwnode_handle

View file

@ -13,6 +13,7 @@
#ifndef _LINUX_PROPERTY_H_
#define _LINUX_PROPERTY_H_
#include <linux/bits.h>
#include <linux/fwnode.h>
#include <linux/types.h>
@ -304,6 +305,23 @@ struct fwnode_handle *
fwnode_graph_get_remote_node(const struct fwnode_handle *fwnode, u32 port,
u32 endpoint);
/*
* Fwnode lookup flags
*
* @FWNODE_GRAPH_ENDPOINT_NEXT: In the case of no exact match, look for the
* closest endpoint ID greater than the specified
* one.
* @FWNODE_GRAPH_DEVICE_DISABLED: That the device to which the remote
* endpoint of the given endpoint belongs to,
* may be disabled.
*/
#define FWNODE_GRAPH_ENDPOINT_NEXT BIT(0)
#define FWNODE_GRAPH_DEVICE_DISABLED BIT(1)
struct fwnode_handle *
fwnode_graph_get_endpoint_by_id(const struct fwnode_handle *fwnode,
u32 port, u32 endpoint, unsigned long flags);
#define fwnode_graph_for_each_endpoint(fwnode, child) \
for (child = NULL; \
(child = fwnode_graph_get_next_endpoint(fwnode, child)); )