Commit d7cf5590 authored by Heikki Krogerus's avatar Heikki Krogerus Committed by Greg Kroah-Hartman
Browse files

device property: Move fwnode_connection_find_match() under drivers/base/property.c



The function is now only a helper that searches the
connection from device graph and then by checking if the
supplied connection identifier matches a property that
contains reference.

Signed-off-by: default avatarHeikki Krogerus <heikki.krogerus@linux.intel.com>
Link: https://lore.kernel.org/r/20200907120532.37611-2-heikki.krogerus@linux.intel.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 28d9fdf0
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -6,7 +6,7 @@ obj-y := component.o core.o bus.o dd.o syscore.o \
			   cpu.o firmware.o init.o map.o devres.o \
			   attribute_container.o transport_class.o \
			   topology.o container.o property.o cacheinfo.o \
			   devcon.o swnode.o
			   swnode.o
obj-$(CONFIG_DEVTMPFS)	+= devtmpfs.o
obj-y			+= power/
obj-$(CONFIG_ISA_BUS_API)	+= isa.o

drivers/base/devcon.c

deleted100644 → 0
+0 −101
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
/**
 * Device connections
 *
 * Copyright (C) 2018 Intel Corporation
 * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com>
 */

#include <linux/device.h>
#include <linux/property.h>

static void *
fwnode_graph_devcon_match(struct fwnode_handle *fwnode, const char *con_id,
			  void *data, devcon_match_fn_t match)
{
	struct fwnode_handle *node;
	struct fwnode_handle *ep;
	void *ret;

	fwnode_graph_for_each_endpoint(fwnode, ep) {
		node = fwnode_graph_get_remote_port_parent(ep);
		if (!fwnode_device_is_available(node))
			continue;

		ret = match(node, con_id, data);
		fwnode_handle_put(node);
		if (ret) {
			fwnode_handle_put(ep);
			return ret;
		}
	}
	return NULL;
}

static void *
fwnode_devcon_match(struct fwnode_handle *fwnode, const char *con_id,
		    void *data, devcon_match_fn_t match)
{
	struct fwnode_handle *node;
	void *ret;
	int i;

	for (i = 0; ; i++) {
		node = fwnode_find_reference(fwnode, con_id, i);
		if (IS_ERR(node))
			break;

		ret = match(node, NULL, data);
		fwnode_handle_put(node);
		if (ret)
			return ret;
	}

	return NULL;
}

/**
 * fwnode_connection_find_match - Find connection from a device node
 * @fwnode: Device node with the connection
 * @con_id: Identifier for the connection
 * @data: Data for the match function
 * @match: Function to check and convert the connection description
 *
 * Find a connection with unique identifier @con_id between @fwnode and another
 * device node. @match will be used to convert the connection description to
 * data the caller is expecting to be returned.
 */
void *fwnode_connection_find_match(struct fwnode_handle *fwnode,
				   const char *con_id, void *data,
				   devcon_match_fn_t match)
{
	void *ret;

	if (!fwnode || !match)
		return NULL;

	ret = fwnode_graph_devcon_match(fwnode, con_id, data, match);
	if (ret)
		return ret;

	return fwnode_devcon_match(fwnode, con_id, data, match);
}
EXPORT_SYMBOL_GPL(fwnode_connection_find_match);

/**
 * device_connection_find_match - Find physical connection to a device
 * @dev: Device with the connection
 * @con_id: Identifier for the connection
 * @data: Data for the match function
 * @match: Function to check and convert the connection description
 *
 * Find a connection with unique identifier @con_id between @dev and another
 * device. @match will be used to convert the connection description to data the
 * caller is expecting to be returned.
 */
void *device_connection_find_match(struct device *dev, const char *con_id,
				   void *data, devcon_match_fn_t match)
{
	return fwnode_connection_find_match(dev_fwnode(dev), con_id, data, match);
}
EXPORT_SYMBOL_GPL(device_connection_find_match);
+73 −0
Original line number Diff line number Diff line
@@ -1184,3 +1184,76 @@ const void *device_get_match_data(struct device *dev)
	return fwnode_call_ptr_op(dev_fwnode(dev), device_get_match_data, dev);
}
EXPORT_SYMBOL_GPL(device_get_match_data);

static void *
fwnode_graph_devcon_match(struct fwnode_handle *fwnode, const char *con_id,
			  void *data, devcon_match_fn_t match)
{
	struct fwnode_handle *node;
	struct fwnode_handle *ep;
	void *ret;

	fwnode_graph_for_each_endpoint(fwnode, ep) {
		node = fwnode_graph_get_remote_port_parent(ep);
		if (!fwnode_device_is_available(node))
			continue;

		ret = match(node, con_id, data);
		fwnode_handle_put(node);
		if (ret) {
			fwnode_handle_put(ep);
			return ret;
		}
	}
	return NULL;
}

static void *
fwnode_devcon_match(struct fwnode_handle *fwnode, const char *con_id,
		    void *data, devcon_match_fn_t match)
{
	struct fwnode_handle *node;
	void *ret;
	int i;

	for (i = 0; ; i++) {
		node = fwnode_find_reference(fwnode, con_id, i);
		if (IS_ERR(node))
			break;

		ret = match(node, NULL, data);
		fwnode_handle_put(node);
		if (ret)
			return ret;
	}

	return NULL;
}

/**
 * fwnode_connection_find_match - Find connection from a device node
 * @fwnode: Device node with the connection
 * @con_id: Identifier for the connection
 * @data: Data for the match function
 * @match: Function to check and convert the connection description
 *
 * Find a connection with unique identifier @con_id between @fwnode and another
 * device node. @match will be used to convert the connection description to
 * data the caller is expecting to be returned.
 */
void *fwnode_connection_find_match(struct fwnode_handle *fwnode,
				   const char *con_id, void *data,
				   devcon_match_fn_t match)
{
	void *ret;

	if (!fwnode || !match)
		return NULL;

	ret = fwnode_graph_devcon_match(fwnode, con_id, data, match);
	if (ret)
		return ret;

	return fwnode_devcon_match(fwnode, con_id, data, match);
}
EXPORT_SYMBOL_GPL(fwnode_connection_find_match);
+0 −9
Original line number Diff line number Diff line
@@ -292,15 +292,6 @@ struct device_dma_parameters {
	unsigned long segment_boundary_mask;
};

typedef void *(*devcon_match_fn_t)(struct fwnode_handle *fwnode, const char *id,
				   void *data);

void *fwnode_connection_find_match(struct fwnode_handle *fwnode,
				   const char *con_id, void *data,
				   devcon_match_fn_t match);
void *device_connection_find_match(struct device *dev, const char *con_id,
				   void *data, devcon_match_fn_t match);

/**
 * enum device_link_state - Device link states.
 * @DL_STATE_NONE: The presence of the drivers is not being tracked.
+14 −0
Original line number Diff line number Diff line
@@ -418,6 +418,20 @@ fwnode_graph_get_endpoint_by_id(const struct fwnode_handle *fwnode,
int fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode,
				struct fwnode_endpoint *endpoint);

typedef void *(*devcon_match_fn_t)(struct fwnode_handle *fwnode, const char *id,
				   void *data);

void *fwnode_connection_find_match(struct fwnode_handle *fwnode,
				   const char *con_id, void *data,
				   devcon_match_fn_t match);

static inline void *device_connection_find_match(struct device *dev,
						 const char *con_id, void *data,
						 devcon_match_fn_t match)
{
	return fwnode_connection_find_match(dev_fwnode(dev), con_id, data, match);
}

/* -------------------------------------------------------------------------- */
/* Software fwnode support - when HW description is incomplete or missing */