1
2
3
4
5
6
7
8
9
10#include <linux/device.h>
11#include <linux/list.h>
12#include <linux/mutex.h>
13#include <linux/usb/typec_mux.h>
14
15static DEFINE_MUTEX(switch_lock);
16static DEFINE_MUTEX(mux_lock);
17static LIST_HEAD(switch_list);
18static LIST_HEAD(mux_list);
19
20static void *typec_switch_match(struct device_connection *con, int ep,
21 void *data)
22{
23 struct typec_switch *sw;
24
25 list_for_each_entry(sw, &switch_list, entry)
26 if (!strcmp(con->endpoint[ep], dev_name(sw->dev)))
27 return sw;
28
29
30
31
32
33 return ERR_PTR(-EPROBE_DEFER);
34}
35
36
37
38
39
40
41
42
43
44
45struct typec_switch *typec_switch_get(struct device *dev)
46{
47 struct typec_switch *sw;
48
49 mutex_lock(&switch_lock);
50 sw = device_connection_find_match(dev, "typec-switch", NULL,
51 typec_switch_match);
52 if (!IS_ERR_OR_NULL(sw))
53 get_device(sw->dev);
54 mutex_unlock(&switch_lock);
55
56 return sw;
57}
58EXPORT_SYMBOL_GPL(typec_switch_get);
59
60
61
62
63
64
65
66void typec_switch_put(struct typec_switch *sw)
67{
68 if (!IS_ERR_OR_NULL(sw))
69 put_device(sw->dev);
70}
71EXPORT_SYMBOL_GPL(typec_switch_put);
72
73
74
75
76
77
78
79
80
81
82int typec_switch_register(struct typec_switch *sw)
83{
84 mutex_lock(&switch_lock);
85 list_add_tail(&sw->entry, &switch_list);
86 mutex_unlock(&switch_lock);
87
88 return 0;
89}
90EXPORT_SYMBOL_GPL(typec_switch_register);
91
92
93
94
95
96
97
98void typec_switch_unregister(struct typec_switch *sw)
99{
100 mutex_lock(&switch_lock);
101 list_del(&sw->entry);
102 mutex_unlock(&switch_lock);
103}
104EXPORT_SYMBOL_GPL(typec_switch_unregister);
105
106
107
108static void *typec_mux_match(struct device_connection *con, int ep, void *data)
109{
110 struct typec_mux *mux;
111
112 list_for_each_entry(mux, &mux_list, entry)
113 if (!strcmp(con->endpoint[ep], dev_name(mux->dev)))
114 return mux;
115
116
117
118
119
120 return ERR_PTR(-EPROBE_DEFER);
121}
122
123
124
125
126
127
128
129
130
131
132
133struct typec_mux *typec_mux_get(struct device *dev, const char *name)
134{
135 struct typec_mux *mux;
136
137 mutex_lock(&mux_lock);
138 mux = device_connection_find_match(dev, name, NULL, typec_mux_match);
139 if (!IS_ERR_OR_NULL(mux))
140 get_device(mux->dev);
141 mutex_unlock(&mux_lock);
142
143 return mux;
144}
145EXPORT_SYMBOL_GPL(typec_mux_get);
146
147
148
149
150
151
152
153void typec_mux_put(struct typec_mux *mux)
154{
155 if (!IS_ERR_OR_NULL(mux))
156 put_device(mux->dev);
157}
158EXPORT_SYMBOL_GPL(typec_mux_put);
159
160
161
162
163
164
165
166
167
168
169int typec_mux_register(struct typec_mux *mux)
170{
171 mutex_lock(&mux_lock);
172 list_add_tail(&mux->entry, &mux_list);
173 mutex_unlock(&mux_lock);
174
175 return 0;
176}
177EXPORT_SYMBOL_GPL(typec_mux_register);
178
179
180
181
182
183
184
185void typec_mux_unregister(struct typec_mux *mux)
186{
187 mutex_lock(&mux_lock);
188 list_del(&mux->entry);
189 mutex_unlock(&mux_lock);
190}
191EXPORT_SYMBOL_GPL(typec_mux_unregister);
192