Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 548aa0e3 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull device properties framework updates from Rafael Wysocki:
 "These mostly rearrange the device properties core code and add a few
  helper functions to it as a foundation for future work.

  Specifics:

   - Rearrange the core device properties code by moving the code
     specific to each supported platform configuration framework (ACPI,
     DT and build-in) into a separate file (Sakari Ailus).

   - Add helper functions for accessing device properties in a
     firmware-agnostic way (Sakari Ailus, Kieran Bingham)"

* tag 'devprop-4.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  device property: Add fwnode_graph_get_port_parent
  device property: Add FW type agnostic fwnode_graph_get_remote_node
  device property: Introduce fwnode_device_is_available()
  device property: Move fwnode graph ops to firmware specific locations
  device property: Move FW type specific functionality to FW specific files
  ACPI: Constify argument to acpi_device_is_present()
parents 32261868 6a71d8d7
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -262,8 +262,10 @@ int acpi_bus_init_power(struct acpi_device *device)
		return -EINVAL;

	device->power.state = ACPI_STATE_UNKNOWN;
	if (!acpi_device_is_present(device))
	if (!acpi_device_is_present(device)) {
		device->flags.initialized = false;
		return -ENXIO;
	}

	result = acpi_device_get_power(device, &state);
	if (result)
+1 −1
Original line number Diff line number Diff line
@@ -111,7 +111,7 @@ int acpi_device_setup_files(struct acpi_device *dev);
void acpi_device_remove_files(struct acpi_device *dev);
void acpi_device_add_finalize(struct acpi_device *device);
void acpi_free_pnp_ids(struct acpi_device_pnp *pnp);
bool acpi_device_is_present(struct acpi_device *adev);
bool acpi_device_is_present(const struct acpi_device *adev);
bool acpi_device_is_battery(struct acpi_device *adev);
bool acpi_device_is_first_physical_node(struct acpi_device *adev,
					const struct device *dev);
+117 −0
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@ static bool acpi_nondev_subnode_extract(const union acpi_object *desc,

	dn->name = link->package.elements[0].string.pointer;
	dn->fwnode.type = FWNODE_ACPI_DATA;
	dn->fwnode.ops = &acpi_fwnode_ops;
	dn->parent = parent;
	INIT_LIST_HEAD(&dn->data.subnodes);

@@ -1119,3 +1120,119 @@ int acpi_graph_get_remote_endpoint(struct fwnode_handle *fwnode,

	return 0;
}

static bool acpi_fwnode_device_is_available(struct fwnode_handle *fwnode)
{
	if (!is_acpi_device_node(fwnode))
		return false;

	return acpi_device_is_present(to_acpi_device_node(fwnode));
}

static bool acpi_fwnode_property_present(struct fwnode_handle *fwnode,
					 const char *propname)
{
	return !acpi_node_prop_get(fwnode, propname, NULL);
}

static int acpi_fwnode_property_read_int_array(struct fwnode_handle *fwnode,
					       const char *propname,
					       unsigned int elem_size,
					       void *val, size_t nval)
{
	enum dev_prop_type type;

	switch (elem_size) {
	case sizeof(u8):
		type = DEV_PROP_U8;
		break;
	case sizeof(u16):
		type = DEV_PROP_U16;
		break;
	case sizeof(u32):
		type = DEV_PROP_U32;
		break;
	case sizeof(u64):
		type = DEV_PROP_U64;
		break;
	default:
		return -ENXIO;
	}

	return acpi_node_prop_read(fwnode, propname, type, val, nval);
}

static int acpi_fwnode_property_read_string_array(struct fwnode_handle *fwnode,
						  const char *propname,
						  const char **val, size_t nval)
{
	return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
				   val, nval);
}

static struct fwnode_handle *
acpi_fwnode_get_named_child_node(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 struct fwnode_handle *
acpi_fwnode_graph_get_next_endpoint(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(struct fwnode_handle *fwnode)
{
	struct fwnode_handle *endpoint = NULL;

	acpi_graph_get_remote_endpoint(fwnode, NULL, NULL, &endpoint);

	return endpoint;
}

static int acpi_fwnode_graph_parse_endpoint(struct fwnode_handle *fwnode,
					    struct fwnode_endpoint *endpoint)
{
	struct fwnode_handle *port_fwnode = fwnode_get_parent(fwnode);

	endpoint->local_fwnode = fwnode;

	fwnode_property_read_u32(port_fwnode, "port", &endpoint->port);
	fwnode_property_read_u32(fwnode, "endpoint", &endpoint->id);

	return 0;
}

const struct fwnode_operations acpi_fwnode_ops = {
	.device_is_available = acpi_fwnode_device_is_available,
	.property_present = acpi_fwnode_property_present,
	.property_read_int_array = acpi_fwnode_property_read_int_array,
	.property_read_string_array = acpi_fwnode_property_read_string_array,
	.get_parent = acpi_node_get_parent,
	.get_next_child_node = acpi_get_next_subnode,
	.get_named_child_node = acpi_fwnode_get_named_child_node,
	.graph_get_next_endpoint = acpi_fwnode_graph_get_next_endpoint,
	.graph_get_remote_endpoint = acpi_fwnode_graph_get_remote_endpoint,
	.graph_get_port_parent = acpi_node_get_parent,
	.graph_parse_endpoint = acpi_fwnode_graph_parse_endpoint,
};
+4 −6
Original line number Diff line number Diff line
@@ -1468,6 +1468,7 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
	device->handle = handle;
	device->parent = acpi_bus_get_parent(handle);
	device->fwnode.type = FWNODE_ACPI;
	device->fwnode.ops = &acpi_fwnode_ops;
	acpi_set_device_status(device, sta);
	acpi_device_get_busid(device);
	acpi_set_pnp_ids(handle, &device->pnp, type);
@@ -1600,13 +1601,9 @@ static int acpi_bus_type_and_status(acpi_handle handle, int *type,
	return 0;
}

bool acpi_device_is_present(struct acpi_device *adev)
bool acpi_device_is_present(const struct acpi_device *adev)
{
	if (adev->status.present || adev->status.functional)
		return true;

	adev->flags.initialized = false;
	return false;
	return adev->status.present || adev->status.functional;
}

static bool acpi_scan_handler_matching(struct acpi_scan_handler *handler,
@@ -1839,6 +1836,7 @@ static void acpi_bus_attach(struct acpi_device *device)
	acpi_bus_get_status(device);
	/* Skip devices that are not present. */
	if (!acpi_device_is_present(device)) {
		device->flags.initialized = false;
		acpi_device_clear_enumerated(device);
		device->flags.power_manageable = 0;
		return;
+149 −199
Original line number Diff line number Diff line
@@ -187,6 +187,50 @@ struct fwnode_handle *dev_fwnode(struct device *dev)
}
EXPORT_SYMBOL_GPL(dev_fwnode);

static bool pset_fwnode_property_present(struct fwnode_handle *fwnode,
					 const char *propname)
{
	return !!pset_prop_get(to_pset_node(fwnode), propname);
}

static int pset_fwnode_read_int_array(struct fwnode_handle *fwnode,
				      const char *propname,
				      unsigned int elem_size, void *val,
				      size_t nval)
{
	struct property_set *node = to_pset_node(fwnode);

	if (!val)
		return pset_prop_count_elems_of_size(node, propname, elem_size);

	switch (elem_size) {
	case sizeof(u8):
		return pset_prop_read_u8_array(node, propname, val, nval);
	case sizeof(u16):
		return pset_prop_read_u16_array(node, propname, val, nval);
	case sizeof(u32):
		return pset_prop_read_u32_array(node, propname, val, nval);
	case sizeof(u64):
		return pset_prop_read_u64_array(node, propname, val, nval);
	}

	return -ENXIO;
}

static int pset_fwnode_property_read_string_array(struct fwnode_handle *fwnode,
						  const char *propname,
						  const char **val, size_t nval)
{
	return pset_prop_read_string_array(to_pset_node(fwnode), propname,
					   val, nval);
}

static const struct fwnode_operations pset_fwnode_ops = {
	.property_present = pset_fwnode_property_present,
	.property_read_int_array = pset_fwnode_read_int_array,
	.property_read_string_array = pset_fwnode_property_read_string_array,
};

/**
 * device_property_present - check if a property of a device is present
 * @dev: Device whose property is being checked
@@ -200,18 +244,6 @@ bool device_property_present(struct device *dev, const char *propname)
}
EXPORT_SYMBOL_GPL(device_property_present);

static bool __fwnode_property_present(struct fwnode_handle *fwnode,
				      const char *propname)
{
	if (is_of_node(fwnode))
		return of_property_read_bool(to_of_node(fwnode), propname);
	else if (is_acpi_node(fwnode))
		return !acpi_node_prop_get(fwnode, propname, NULL);
	else if (is_pset_node(fwnode))
		return !!pset_prop_get(to_pset_node(fwnode), propname);
	return false;
}

/**
 * fwnode_property_present - check if a property of a firmware node is present
 * @fwnode: Firmware node whose property to check
@@ -221,10 +253,11 @@ bool fwnode_property_present(struct fwnode_handle *fwnode, const char *propname)
{
	bool ret;

	ret = __fwnode_property_present(fwnode, propname);
	ret = fwnode_call_int_op(fwnode, property_present, propname);
	if (ret == false && !IS_ERR_OR_NULL(fwnode) &&
	    !IS_ERR_OR_NULL(fwnode->secondary))
		ret = __fwnode_property_present(fwnode->secondary, propname);
		ret = fwnode_call_int_op(fwnode->secondary, property_present,
					 propname);
	return ret;
}
EXPORT_SYMBOL_GPL(fwnode_property_present);
@@ -398,42 +431,23 @@ int device_property_match_string(struct device *dev, const char *propname,
}
EXPORT_SYMBOL_GPL(device_property_match_string);

#define OF_DEV_PROP_READ_ARRAY(node, propname, type, val, nval)				\
	(val) ? of_property_read_##type##_array((node), (propname), (val), (nval))	\
	      : of_property_count_elems_of_size((node), (propname), sizeof(type))

#define PSET_PROP_READ_ARRAY(node, propname, type, val, nval)				\
	(val) ? pset_prop_read_##type##_array((node), (propname), (val), (nval))	\
	      : pset_prop_count_elems_of_size((node), (propname), sizeof(type))

#define FWNODE_PROP_READ(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_)	\
({											\
	int _ret_;									\
	if (is_of_node(_fwnode_))							\
		_ret_ = OF_DEV_PROP_READ_ARRAY(to_of_node(_fwnode_), _propname_,	\
					       _type_, _val_, _nval_);			\
	else if (is_acpi_node(_fwnode_))						\
		_ret_ = acpi_node_prop_read(_fwnode_, _propname_, _proptype_,		\
					    _val_, _nval_);				\
	else if (is_pset_node(_fwnode_)) 						\
		_ret_ = PSET_PROP_READ_ARRAY(to_pset_node(_fwnode_), _propname_,	\
					     _type_, _val_, _nval_);			\
	else										\
		_ret_ = -ENXIO;								\
	_ret_;										\
})

#define FWNODE_PROP_READ_ARRAY(_fwnode_, _propname_, _type_, _proptype_, _val_, _nval_)	\
({											\
	int _ret_;									\
	_ret_ = FWNODE_PROP_READ(_fwnode_, _propname_, _type_, _proptype_,		\
				 _val_, _nval_);					\
	if (_ret_ == -EINVAL && !IS_ERR_OR_NULL(_fwnode_) &&				\
	    !IS_ERR_OR_NULL(_fwnode_->secondary))					\
		_ret_ = FWNODE_PROP_READ(_fwnode_->secondary, _propname_, _type_,	\
				_proptype_, _val_, _nval_);				\
	_ret_;										\
})
static int fwnode_property_read_int_array(struct fwnode_handle *fwnode,
					  const char *propname,
					  unsigned int elem_size, void *val,
					  size_t nval)
{
	int ret;

	ret = fwnode_call_int_op(fwnode, property_read_int_array, propname,
				 elem_size, val, nval);
	if (ret == -EINVAL && !IS_ERR_OR_NULL(fwnode) &&
	    !IS_ERR_OR_NULL(fwnode->secondary))
		ret = fwnode_call_int_op(
			fwnode->secondary, property_read_int_array, propname,
			elem_size, val, nval);

	return ret;
}

/**
 * fwnode_property_read_u8_array - return a u8 array property of firmware node
@@ -456,7 +470,7 @@ EXPORT_SYMBOL_GPL(device_property_match_string);
int fwnode_property_read_u8_array(struct fwnode_handle *fwnode,
				  const char *propname, u8 *val, size_t nval)
{
	return FWNODE_PROP_READ_ARRAY(fwnode, propname, u8, DEV_PROP_U8,
	return fwnode_property_read_int_array(fwnode, propname, sizeof(u8),
					      val, nval);
}
EXPORT_SYMBOL_GPL(fwnode_property_read_u8_array);
@@ -482,7 +496,7 @@ EXPORT_SYMBOL_GPL(fwnode_property_read_u8_array);
int fwnode_property_read_u16_array(struct fwnode_handle *fwnode,
				   const char *propname, u16 *val, size_t nval)
{
	return FWNODE_PROP_READ_ARRAY(fwnode, propname, u16, DEV_PROP_U16,
	return fwnode_property_read_int_array(fwnode, propname, sizeof(u16),
					      val, nval);
}
EXPORT_SYMBOL_GPL(fwnode_property_read_u16_array);
@@ -508,7 +522,7 @@ EXPORT_SYMBOL_GPL(fwnode_property_read_u16_array);
int fwnode_property_read_u32_array(struct fwnode_handle *fwnode,
				   const char *propname, u32 *val, size_t nval)
{
	return FWNODE_PROP_READ_ARRAY(fwnode, propname, u32, DEV_PROP_U32,
	return fwnode_property_read_int_array(fwnode, propname, sizeof(u32),
					      val, nval);
}
EXPORT_SYMBOL_GPL(fwnode_property_read_u32_array);
@@ -534,29 +548,11 @@ EXPORT_SYMBOL_GPL(fwnode_property_read_u32_array);
int fwnode_property_read_u64_array(struct fwnode_handle *fwnode,
				   const char *propname, u64 *val, size_t nval)
{
	return FWNODE_PROP_READ_ARRAY(fwnode, propname, u64, DEV_PROP_U64,
	return fwnode_property_read_int_array(fwnode, propname, sizeof(u64),
					      val, nval);
}
EXPORT_SYMBOL_GPL(fwnode_property_read_u64_array);

static int __fwnode_property_read_string_array(struct fwnode_handle *fwnode,
					       const char *propname,
					       const char **val, size_t nval)
{
	if (is_of_node(fwnode))
		return val ?
			of_property_read_string_array(to_of_node(fwnode),
						      propname, val, nval) :
			of_property_count_strings(to_of_node(fwnode), propname);
	else if (is_acpi_node(fwnode))
		return acpi_node_prop_read(fwnode, propname, DEV_PROP_STRING,
					   val, nval);
	else if (is_pset_node(fwnode))
		return pset_prop_read_string_array(to_pset_node(fwnode),
						   propname, val, nval);
	return -ENXIO;
}

/**
 * fwnode_property_read_string_array - return string array property of a node
 * @fwnode: Firmware node to get the property of
@@ -581,11 +577,13 @@ int fwnode_property_read_string_array(struct fwnode_handle *fwnode,
{
	int ret;

	ret = __fwnode_property_read_string_array(fwnode, propname, val, nval);
	ret = fwnode_call_int_op(fwnode, property_read_string_array, propname,
				 val, nval);
	if (ret == -EINVAL && !IS_ERR_OR_NULL(fwnode) &&
	    !IS_ERR_OR_NULL(fwnode->secondary))
		ret = __fwnode_property_read_string_array(fwnode->secondary,
							  propname, val, nval);
		ret = fwnode_call_int_op(fwnode->secondary,
					 property_read_string_array, propname,
					 val, nval);
	return ret;
}
EXPORT_SYMBOL_GPL(fwnode_property_read_string_array);
@@ -903,6 +901,7 @@ int device_add_properties(struct device *dev,
		return PTR_ERR(p);

	p->fwnode.type = FWNODE_PDATA;
	p->fwnode.ops = &pset_fwnode_ops;
	set_secondary_fwnode(dev, &p->fwnode);
	return 0;
}
@@ -938,19 +937,7 @@ EXPORT_SYMBOL_GPL(fwnode_get_next_parent);
 */
struct fwnode_handle *fwnode_get_parent(struct fwnode_handle *fwnode)
{
	struct fwnode_handle *parent = NULL;

	if (is_of_node(fwnode)) {
		struct device_node *node;

		node = of_get_parent(to_of_node(fwnode));
		if (node)
			parent = &node->fwnode;
	} else if (is_acpi_node(fwnode)) {
		parent = acpi_node_get_parent(fwnode);
	}

	return parent;
	return fwnode_call_ptr_op(fwnode, get_parent);
}
EXPORT_SYMBOL_GPL(fwnode_get_parent);

@@ -962,18 +949,7 @@ EXPORT_SYMBOL_GPL(fwnode_get_parent);
struct fwnode_handle *fwnode_get_next_child_node(struct fwnode_handle *fwnode,
						 struct fwnode_handle *child)
{
	if (is_of_node(fwnode)) {
		struct device_node *node;

		node = of_get_next_available_child(to_of_node(fwnode),
						   to_of_node(child));
		if (node)
			return &node->fwnode;
	} else if (is_acpi_node(fwnode)) {
		return acpi_get_next_subnode(fwnode, child);
	}

	return NULL;
	return fwnode_call_ptr_op(fwnode, get_next_child_node, child);
}
EXPORT_SYMBOL_GPL(fwnode_get_next_child_node);

@@ -1005,23 +981,7 @@ EXPORT_SYMBOL_GPL(device_get_next_child_node);
struct fwnode_handle *fwnode_get_named_child_node(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 (is_of_node(child)) {
			if (!of_node_cmp(to_of_node(child)->name, childname))
				return child;
		} else if (is_acpi_data_node(child)) {
			if (acpi_data_node_match(child, childname))
				return child;
		}
	}

	return NULL;
	return fwnode_call_ptr_op(fwnode, get_named_child_node, childname);
}
EXPORT_SYMBOL_GPL(fwnode_get_named_child_node);

@@ -1043,8 +1003,7 @@ EXPORT_SYMBOL_GPL(device_get_named_child_node);
 */
void fwnode_handle_get(struct fwnode_handle *fwnode)
{
	if (is_of_node(fwnode))
		of_node_get(to_of_node(fwnode));
	fwnode_call_void_op(fwnode, get);
}
EXPORT_SYMBOL_GPL(fwnode_handle_get);

@@ -1058,11 +1017,20 @@ EXPORT_SYMBOL_GPL(fwnode_handle_get);
 */
void fwnode_handle_put(struct fwnode_handle *fwnode)
{
	if (is_of_node(fwnode))
		of_node_put(to_of_node(fwnode));
	fwnode_call_void_op(fwnode, put);
}
EXPORT_SYMBOL_GPL(fwnode_handle_put);

/**
 * fwnode_device_is_available - check if a device is available for use
 * @fwnode: Pointer to the fwnode of the device.
 */
bool fwnode_device_is_available(struct fwnode_handle *fwnode)
{
	return fwnode_call_int_op(fwnode, device_is_available);
}
EXPORT_SYMBOL_GPL(fwnode_device_is_available);

/**
 * device_get_child_node_count - return the number of child nodes for device
 * @dev: Device to cound the child nodes for
@@ -1198,26 +1166,29 @@ struct fwnode_handle *
fwnode_graph_get_next_endpoint(struct fwnode_handle *fwnode,
			       struct fwnode_handle *prev)
{
	struct fwnode_handle *endpoint = NULL;

	if (is_of_node(fwnode)) {
		struct device_node *node;
	return fwnode_call_ptr_op(fwnode, graph_get_next_endpoint, prev);
}
EXPORT_SYMBOL_GPL(fwnode_graph_get_next_endpoint);

		node = of_graph_get_next_endpoint(to_of_node(fwnode),
						  to_of_node(prev));
/**
 * fwnode_graph_get_port_parent - Return the device fwnode of a port endpoint
 * @endpoint: Endpoint firmware node of the port
 *
 * Return: the firmware node of the device the @endpoint belongs to.
 */
struct fwnode_handle *
fwnode_graph_get_port_parent(struct fwnode_handle *endpoint)
{
	struct fwnode_handle *port, *parent;

		if (node)
			endpoint = &node->fwnode;
	} else if (is_acpi_node(fwnode)) {
		endpoint = acpi_graph_get_next_endpoint(fwnode, prev);
		if (IS_ERR(endpoint))
			endpoint = NULL;
	}
	port = fwnode_get_parent(endpoint);
	parent = fwnode_call_ptr_op(port, graph_get_port_parent);

	return endpoint;
	fwnode_handle_put(port);

	return parent;
}
EXPORT_SYMBOL_GPL(fwnode_graph_get_next_endpoint);
EXPORT_SYMBOL_GPL(fwnode_graph_get_port_parent);

/**
 * fwnode_graph_get_remote_port_parent - Return fwnode of a remote device
@@ -1228,22 +1199,12 @@ EXPORT_SYMBOL_GPL(fwnode_graph_get_next_endpoint);
struct fwnode_handle *
fwnode_graph_get_remote_port_parent(struct fwnode_handle *fwnode)
{
	struct fwnode_handle *parent = NULL;
	struct fwnode_handle *endpoint, *parent;

	if (is_of_node(fwnode)) {
		struct device_node *node;
	endpoint = fwnode_graph_get_remote_endpoint(fwnode);
	parent = fwnode_graph_get_port_parent(endpoint);

		node = of_graph_get_remote_port_parent(to_of_node(fwnode));
		if (node)
			parent = &node->fwnode;
	} else if (is_acpi_node(fwnode)) {
		int ret;

		ret = acpi_graph_get_remote_endpoint(fwnode, &parent, NULL,
						     NULL);
		if (ret)
			return NULL;
	}
	fwnode_handle_put(endpoint);

	return parent;
}
@@ -1257,23 +1218,7 @@ EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_port_parent);
 */
struct fwnode_handle *fwnode_graph_get_remote_port(struct fwnode_handle *fwnode)
{
	struct fwnode_handle *port = NULL;

	if (is_of_node(fwnode)) {
		struct device_node *node;

		node = of_graph_get_remote_port(to_of_node(fwnode));
		if (node)
			port = &node->fwnode;
	} else if (is_acpi_node(fwnode)) {
		int ret;

		ret = acpi_graph_get_remote_endpoint(fwnode, NULL, &port, NULL);
		if (ret)
			return NULL;
	}

	return port;
	return fwnode_get_next_parent(fwnode_graph_get_remote_endpoint(fwnode));
}
EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_port);

@@ -1286,27 +1231,46 @@ EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_port);
struct fwnode_handle *
fwnode_graph_get_remote_endpoint(struct fwnode_handle *fwnode)
{
	struct fwnode_handle *endpoint = NULL;
	return fwnode_call_ptr_op(fwnode, graph_get_remote_endpoint);
}
EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_endpoint);

	if (is_of_node(fwnode)) {
		struct device_node *node;
/**
 * fwnode_graph_get_remote_node - get remote parent node for given port/endpoint
 * @fwnode: pointer to parent fwnode_handle containing graph port/endpoint
 * @port_id: identifier of the parent port node
 * @endpoint_id: identifier of the endpoint node
 *
 * Return: Remote fwnode handle associated with remote endpoint node linked
 *	   to @node. Use fwnode_node_put() on it when done.
 */
struct fwnode_handle *fwnode_graph_get_remote_node(struct fwnode_handle *fwnode,
						   u32 port_id, u32 endpoint_id)
{
	struct fwnode_handle *endpoint = NULL;

		node = of_parse_phandle(to_of_node(fwnode), "remote-endpoint",
					0);
		if (node)
			endpoint = &node->fwnode;
	} else if (is_acpi_node(fwnode)) {
	while ((endpoint = fwnode_graph_get_next_endpoint(fwnode, endpoint))) {
		struct fwnode_endpoint fwnode_ep;
		struct fwnode_handle *remote;
		int ret;

		ret = acpi_graph_get_remote_endpoint(fwnode, NULL, NULL,
						     &endpoint);
		if (ret)
		ret = fwnode_graph_parse_endpoint(endpoint, &fwnode_ep);
		if (ret < 0)
			continue;

		if (fwnode_ep.port != port_id || fwnode_ep.id != endpoint_id)
			continue;

		remote = fwnode_graph_get_remote_port_parent(endpoint);
		if (!remote)
			return NULL;

		return fwnode_device_is_available(remote) ? remote : NULL;
	}

	return endpoint;
	return NULL;
}
EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_endpoint);
EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_node);

/**
 * fwnode_graph_parse_endpoint - parse common endpoint node properties
@@ -1320,22 +1284,8 @@ EXPORT_SYMBOL_GPL(fwnode_graph_get_remote_endpoint);
int fwnode_graph_parse_endpoint(struct fwnode_handle *fwnode,
				struct fwnode_endpoint *endpoint)
{
	struct fwnode_handle *port_fwnode = fwnode_get_parent(fwnode);

	memset(endpoint, 0, sizeof(*endpoint));

	endpoint->local_fwnode = fwnode;

	if (is_acpi_node(port_fwnode)) {
		fwnode_property_read_u32(port_fwnode, "port", &endpoint->port);
		fwnode_property_read_u32(fwnode, "endpoint", &endpoint->id);
	} else {
		fwnode_property_read_u32(port_fwnode, "reg", &endpoint->port);
		fwnode_property_read_u32(fwnode, "reg", &endpoint->id);
	}

	fwnode_handle_put(port_fwnode);

	return 0;
	return fwnode_call_int_op(fwnode, graph_parse_endpoint, endpoint);
}
EXPORT_SYMBOL(fwnode_graph_parse_endpoint);
Loading