hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/usb/typec/mux.c
....@@ -1,5 +1,5 @@
11 // SPDX-License-Identifier: GPL-2.0
2
-/**
2
+/*
33 * USB Type-C Multiplexer/DeMultiplexer Switch support
44 *
55 * Copyright (C) 2018 Intel Corporation
....@@ -16,11 +16,6 @@
1616 #include <linux/usb/typec_mux.h>
1717
1818 #include "bus.h"
19
-
20
-static int name_match(struct device *dev, const void *name)
21
-{
22
- return !strcmp((const char *)name, dev_name(dev));
23
-}
2419
2520 static bool dev_name_ends_with(struct device *dev, const char *suffix)
2621 {
....@@ -39,49 +34,44 @@
3934 return dev_fwnode(dev) == fwnode && dev_name_ends_with(dev, "-switch");
4035 }
4136
42
-static void *typec_switch_match(struct device_connection *con, int ep,
37
+static void *typec_switch_match(struct fwnode_handle *fwnode, const char *id,
4338 void *data)
4439 {
4540 struct device *dev;
4641
47
- if (con->fwnode) {
48
- if (con->id && !fwnode_property_present(con->fwnode, con->id))
49
- return NULL;
42
+ if (id && !fwnode_property_present(fwnode, id))
43
+ return NULL;
5044
51
- dev = class_find_device(&typec_mux_class, NULL, con->fwnode,
52
- switch_fwnode_match);
53
- } else {
54
- dev = class_find_device(&typec_mux_class, NULL,
55
- con->endpoint[ep], name_match);
56
- }
45
+ dev = class_find_device(&typec_mux_class, NULL, fwnode,
46
+ switch_fwnode_match);
5747
5848 return dev ? to_typec_switch(dev) : ERR_PTR(-EPROBE_DEFER);
5949 }
6050
6151 /**
62
- * typec_switch_get - Find USB Type-C orientation switch
63
- * @dev: The caller device
52
+ * fwnode_typec_switch_get - Find USB Type-C orientation switch
53
+ * @fwnode: The caller device node
6454 *
6555 * Finds a switch linked with @dev. Returns a reference to the switch on
6656 * success, NULL if no matching connection was found, or
6757 * ERR_PTR(-EPROBE_DEFER) when a connection was found but the switch
6858 * has not been enumerated yet.
6959 */
70
-struct typec_switch *typec_switch_get(struct device *dev)
60
+struct typec_switch *fwnode_typec_switch_get(struct fwnode_handle *fwnode)
7161 {
7262 struct typec_switch *sw;
7363
74
- sw = device_connection_find_match(dev, "orientation-switch", NULL,
64
+ sw = fwnode_connection_find_match(fwnode, "orientation-switch", NULL,
7565 typec_switch_match);
7666 if (!IS_ERR_OR_NULL(sw))
7767 WARN_ON(!try_module_get(sw->dev.parent->driver->owner));
7868
7969 return sw;
8070 }
81
-EXPORT_SYMBOL_GPL(typec_switch_get);
71
+EXPORT_SYMBOL_GPL(fwnode_typec_switch_get);
8272
8373 /**
84
- * typec_put_switch - Release USB Type-C orientation switch
74
+ * typec_switch_put - Release USB Type-C orientation switch
8575 * @sw: USB Type-C orientation switch
8676 *
8777 * Decrement reference count for @sw.
....@@ -137,7 +127,11 @@
137127 sw->dev.class = &typec_mux_class;
138128 sw->dev.type = &typec_switch_dev_type;
139129 sw->dev.driver_data = desc->drvdata;
140
- dev_set_name(&sw->dev, "%s-switch", dev_name(parent));
130
+ ret = dev_set_name(&sw->dev, "%s-switch", desc->name ? desc->name : dev_name(parent));
131
+ if (ret) {
132
+ put_device(&sw->dev);
133
+ return ERR_PTR(ret);
134
+ }
141135
142136 ret = device_add(&sw->dev);
143137 if (ret) {
....@@ -149,6 +143,16 @@
149143 return sw;
150144 }
151145 EXPORT_SYMBOL_GPL(typec_switch_register);
146
+
147
+int typec_switch_set(struct typec_switch *sw,
148
+ enum typec_orientation orientation)
149
+{
150
+ if (IS_ERR_OR_NULL(sw))
151
+ return 0;
152
+
153
+ return sw->set(sw, orientation);
154
+}
155
+EXPORT_SYMBOL_GPL(typec_switch_set);
152156
153157 /**
154158 * typec_switch_unregister - Unregister USB Type-C orientation switch
....@@ -182,40 +186,35 @@
182186 return dev_fwnode(dev) == fwnode && dev_name_ends_with(dev, "-mux");
183187 }
184188
185
-static void *typec_mux_match(struct device_connection *con, int ep, void *data)
189
+static void *typec_mux_match(struct fwnode_handle *fwnode, const char *id,
190
+ void *data)
186191 {
187192 const struct typec_altmode_desc *desc = data;
188193 struct device *dev;
189194 bool match;
190195 int nval;
191196 u16 *val;
197
+ int ret;
192198 int i;
193
-
194
- if (!con->fwnode) {
195
- dev = class_find_device(&typec_mux_class, NULL,
196
- con->endpoint[ep], name_match);
197
-
198
- return dev ? to_typec_switch(dev) : ERR_PTR(-EPROBE_DEFER);
199
- }
200199
201200 /*
202201 * Check has the identifier already been "consumed". If it
203202 * has, no need to do any extra connection identification.
204203 */
205
- match = !con->id;
204
+ match = !id;
206205 if (match)
207206 goto find_mux;
208207
209208 /* Accessory Mode muxes */
210209 if (!desc) {
211
- match = fwnode_property_present(con->fwnode, "accessory");
210
+ match = fwnode_property_present(fwnode, "accessory");
212211 if (match)
213212 goto find_mux;
214213 return NULL;
215214 }
216215
217216 /* Alternate Mode muxes */
218
- nval = fwnode_property_count_u16(con->fwnode, "svid");
217
+ nval = fwnode_property_count_u16(fwnode, "svid");
219218 if (nval <= 0)
220219 return NULL;
221220
....@@ -223,10 +222,10 @@
223222 if (!val)
224223 return ERR_PTR(-ENOMEM);
225224
226
- nval = fwnode_property_read_u16_array(con->fwnode, "svid", val, nval);
227
- if (nval < 0) {
225
+ ret = fwnode_property_read_u16_array(fwnode, "svid", val, nval);
226
+ if (ret < 0) {
228227 kfree(val);
229
- return ERR_PTR(nval);
228
+ return ERR_PTR(ret);
230229 }
231230
232231 for (i = 0; i < nval; i++) {
....@@ -240,15 +239,15 @@
240239 return NULL;
241240
242241 find_mux:
243
- dev = class_find_device(&typec_mux_class, NULL, con->fwnode,
242
+ dev = class_find_device(&typec_mux_class, NULL, fwnode,
244243 mux_fwnode_match);
245244
246
- return dev ? to_typec_switch(dev) : ERR_PTR(-EPROBE_DEFER);
245
+ return dev ? to_typec_mux(dev) : ERR_PTR(-EPROBE_DEFER);
247246 }
248247
249248 /**
250
- * typec_mux_get - Find USB Type-C Multiplexer
251
- * @dev: The caller device
249
+ * fwnode_typec_mux_get - Find USB Type-C Multiplexer
250
+ * @fwnode: The caller device node
252251 * @desc: Alt Mode description
253252 *
254253 * Finds a mux linked to the caller. This function is primarily meant for the
....@@ -256,19 +255,19 @@
256255 * matching connection was found, or ERR_PTR(-EPROBE_DEFER) when a connection
257256 * was found but the mux has not been enumerated yet.
258257 */
259
-struct typec_mux *typec_mux_get(struct device *dev,
260
- const struct typec_altmode_desc *desc)
258
+struct typec_mux *fwnode_typec_mux_get(struct fwnode_handle *fwnode,
259
+ const struct typec_altmode_desc *desc)
261260 {
262261 struct typec_mux *mux;
263262
264
- mux = device_connection_find_match(dev, "mode-switch", (void *)desc,
263
+ mux = fwnode_connection_find_match(fwnode, "mode-switch", (void *)desc,
265264 typec_mux_match);
266265 if (!IS_ERR_OR_NULL(mux))
267266 WARN_ON(!try_module_get(mux->dev.parent->driver->owner));
268267
269268 return mux;
270269 }
271
-EXPORT_SYMBOL_GPL(typec_mux_get);
270
+EXPORT_SYMBOL_GPL(fwnode_typec_mux_get);
272271
273272 /**
274273 * typec_mux_put - Release handle to a Multiplexer
....@@ -284,6 +283,15 @@
284283 }
285284 }
286285 EXPORT_SYMBOL_GPL(typec_mux_put);
286
+
287
+int typec_mux_set(struct typec_mux *mux, struct typec_mux_state *state)
288
+{
289
+ if (IS_ERR_OR_NULL(mux))
290
+ return 0;
291
+
292
+ return mux->set(mux, state);
293
+}
294
+EXPORT_SYMBOL_GPL(typec_mux_set);
287295
288296 static void typec_mux_release(struct device *dev)
289297 {
....@@ -326,7 +334,11 @@
326334 mux->dev.class = &typec_mux_class;
327335 mux->dev.type = &typec_mux_dev_type;
328336 mux->dev.driver_data = desc->drvdata;
329
- dev_set_name(&mux->dev, "%s-mux", dev_name(parent));
337
+ ret = dev_set_name(&mux->dev, "%s-mux", desc->name ? desc->name : dev_name(parent));
338
+ if (ret) {
339
+ put_device(&mux->dev);
340
+ return ERR_PTR(ret);
341
+ }
330342
331343 ret = device_add(&mux->dev);
332344 if (ret) {