Source
1
1
// SPDX-License-Identifier: GPL-2.0
2
2
/**
3
3
* Device connections
4
4
*
5
5
* Copyright (C) 2018 Intel Corporation
6
6
* Author: Heikki Krogerus <heikki.krogerus@linux.intel.com>
7
7
*/
8
8
9
9
#include <linux/device.h>
10
+
#include <linux/property.h>
10
11
11
12
static DEFINE_MUTEX(devcon_lock);
12
13
static LIST_HEAD(devcon_list);
13
14
15
+
typedef void *(*devcon_match_fn_t)(struct device_connection *con, int ep,
16
+
void *data);
17
+
18
+
static void *
19
+
fwnode_graph_devcon_match(struct fwnode_handle *fwnode, const char *con_id,
20
+
void *data, devcon_match_fn_t match)
21
+
{
22
+
struct device_connection con = { .id = con_id };
23
+
struct fwnode_handle *ep;
24
+
void *ret;
25
+
26
+
fwnode_graph_for_each_endpoint(fwnode, ep) {
27
+
con.fwnode = fwnode_graph_get_remote_port_parent(ep);
28
+
if (!fwnode_device_is_available(con.fwnode))
29
+
continue;
30
+
31
+
ret = match(&con, -1, data);
32
+
fwnode_handle_put(con.fwnode);
33
+
if (ret) {
34
+
fwnode_handle_put(ep);
35
+
return ret;
36
+
}
37
+
}
38
+
return NULL;
39
+
}
40
+
14
41
/**
15
42
* device_connection_find_match - Find physical connection to a device
16
43
* @dev: Device with the connection
17
44
* @con_id: Identifier for the connection
18
45
* @data: Data for the match function
19
46
* @match: Function to check and convert the connection description
20
47
*
21
48
* Find a connection with unique identifier @con_id between @dev and another
22
49
* device. @match will be used to convert the connection description to data the
23
50
* caller is expecting to be returned.
24
51
*/
25
52
void *device_connection_find_match(struct device *dev, const char *con_id,
26
-
void *data,
27
-
void *(*match)(struct device_connection *con,
28
-
int ep, void *data))
53
+
void *data, devcon_match_fn_t match)
29
54
{
55
+
struct fwnode_handle *fwnode = dev_fwnode(dev);
30
56
const char *devname = dev_name(dev);
31
57
struct device_connection *con;
32
58
void *ret = NULL;
33
59
int ep;
34
60
35
61
if (!match)
36
62
return NULL;
37
63
64
+
if (fwnode) {
65
+
ret = fwnode_graph_devcon_match(fwnode, con_id, data, match);
66
+
if (ret)
67
+
return ret;
68
+
}
69
+
38
70
mutex_lock(&devcon_lock);
39
71
40
72
list_for_each_entry(con, &devcon_list, list) {
41
73
ep = match_string(con->endpoint, 2, devname);
42
74
if (ep < 0)
43
75
continue;
44
76
45
77
if (con_id && strcmp(con->id, con_id))
46
78
continue;
47
79