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