Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

usb: typec: mux: Introduce indirection

Rather than directly exposing the implementation's representation of the
typec muxes to the controller/clients, introduce an indirection object.

This enables the introduction of turning this relationship into a
one-to-many in the following patch.

Acked-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
Link: https://lore.kernel.org/r/20220422222351.1297276-5-bjorn.andersson@linaro.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Bjorn Andersson and committed by
Greg Kroah-Hartman
713fd49b b9fa0292

+148 -97
+1 -1
drivers/usb/typec/bus.c
··· 24 24 state.mode = conf; 25 25 state.data = data; 26 26 27 - return alt->mux->set(alt->mux, &state); 27 + return typec_mux_set(alt->mux, &state); 28 28 } 29 29 30 30 static int typec_altmode_set_state(struct typec_altmode *adev,
+121 -72
drivers/usb/typec/mux.c
··· 17 17 #include "class.h" 18 18 #include "mux.h" 19 19 20 + struct typec_switch { 21 + struct typec_switch_dev *sw_dev; 22 + }; 23 + 20 24 static int switch_fwnode_match(struct device *dev, const void *fwnode) 21 25 { 22 - if (!is_typec_switch(dev)) 26 + if (!is_typec_switch_dev(dev)) 23 27 return 0; 24 28 25 29 return dev_fwnode(dev) == fwnode; ··· 53 49 dev = class_find_device(&typec_mux_class, NULL, fwnode, 54 50 switch_fwnode_match); 55 51 56 - return dev ? to_typec_switch(dev) : ERR_PTR(-EPROBE_DEFER); 52 + return dev ? to_typec_switch_dev(dev) : ERR_PTR(-EPROBE_DEFER); 57 53 } 58 54 59 55 /** ··· 67 63 */ 68 64 struct typec_switch *fwnode_typec_switch_get(struct fwnode_handle *fwnode) 69 65 { 66 + struct typec_switch_dev *sw_dev; 70 67 struct typec_switch *sw; 71 68 72 - sw = fwnode_connection_find_match(fwnode, "orientation-switch", NULL, 73 - typec_switch_match); 74 - if (!IS_ERR_OR_NULL(sw)) 75 - WARN_ON(!try_module_get(sw->dev.parent->driver->owner)); 69 + sw = kzalloc(sizeof(*sw), GFP_KERNEL); 70 + if (!sw) 71 + return ERR_PTR(-ENOMEM); 72 + 73 + sw_dev = fwnode_connection_find_match(fwnode, "orientation-switch", NULL, 74 + typec_switch_match); 75 + if (IS_ERR_OR_NULL(sw_dev)) { 76 + kfree(sw); 77 + return ERR_CAST(sw_dev); 78 + } 79 + 80 + WARN_ON(!try_module_get(sw_dev->dev.parent->driver->owner)); 81 + 82 + sw->sw_dev = sw_dev; 76 83 77 84 return sw; 78 85 } ··· 97 82 */ 98 83 void typec_switch_put(struct typec_switch *sw) 99 84 { 100 - if (!IS_ERR_OR_NULL(sw)) { 101 - module_put(sw->dev.parent->driver->owner); 102 - put_device(&sw->dev); 103 - } 85 + struct typec_switch_dev *sw_dev; 86 + 87 + if (IS_ERR_OR_NULL(sw)) 88 + return; 89 + 90 + sw_dev = sw->sw_dev; 91 + 92 + module_put(sw_dev->dev.parent->driver->owner); 93 + put_device(&sw_dev->dev); 94 + kfree(sw); 104 95 } 105 96 EXPORT_SYMBOL_GPL(typec_switch_put); 106 97 107 98 static void typec_switch_release(struct device *dev) 108 99 { 109 - kfree(to_typec_switch(dev)); 100 + kfree(to_typec_switch_dev(dev)); 110 101 } 111 102 112 103 const struct device_type typec_switch_dev_type = { ··· 130 109 * connector to the USB controllers. USB Type-C plugs can be inserted 131 110 * right-side-up or upside-down. 132 111 */ 133 - struct typec_switch * 112 + struct typec_switch_dev * 134 113 typec_switch_register(struct device *parent, 135 114 const struct typec_switch_desc *desc) 136 115 { 137 - struct typec_switch *sw; 116 + struct typec_switch_dev *sw_dev; 138 117 int ret; 139 118 140 119 if (!desc || !desc->set) 141 120 return ERR_PTR(-EINVAL); 142 121 143 - sw = kzalloc(sizeof(*sw), GFP_KERNEL); 144 - if (!sw) 122 + sw_dev = kzalloc(sizeof(*sw_dev), GFP_KERNEL); 123 + if (!sw_dev) 145 124 return ERR_PTR(-ENOMEM); 146 125 147 - sw->set = desc->set; 126 + sw_dev->set = desc->set; 148 127 149 - device_initialize(&sw->dev); 150 - sw->dev.parent = parent; 151 - sw->dev.fwnode = desc->fwnode; 152 - sw->dev.class = &typec_mux_class; 153 - sw->dev.type = &typec_switch_dev_type; 154 - sw->dev.driver_data = desc->drvdata; 155 - ret = dev_set_name(&sw->dev, "%s-switch", desc->name ? desc->name : dev_name(parent)); 128 + device_initialize(&sw_dev->dev); 129 + sw_dev->dev.parent = parent; 130 + sw_dev->dev.fwnode = desc->fwnode; 131 + sw_dev->dev.class = &typec_mux_class; 132 + sw_dev->dev.type = &typec_switch_dev_type; 133 + sw_dev->dev.driver_data = desc->drvdata; 134 + ret = dev_set_name(&sw_dev->dev, "%s-switch", desc->name ? desc->name : dev_name(parent)); 156 135 if (ret) { 157 - put_device(&sw->dev); 136 + put_device(&sw_dev->dev); 158 137 return ERR_PTR(ret); 159 138 } 160 139 161 - ret = device_add(&sw->dev); 140 + ret = device_add(&sw_dev->dev); 162 141 if (ret) { 163 142 dev_err(parent, "failed to register switch (%d)\n", ret); 164 - put_device(&sw->dev); 143 + put_device(&sw_dev->dev); 165 144 return ERR_PTR(ret); 166 145 } 167 146 168 - return sw; 147 + return sw_dev; 169 148 } 170 149 EXPORT_SYMBOL_GPL(typec_switch_register); 171 150 172 151 int typec_switch_set(struct typec_switch *sw, 173 152 enum typec_orientation orientation) 174 153 { 154 + struct typec_switch_dev *sw_dev; 155 + 175 156 if (IS_ERR_OR_NULL(sw)) 176 157 return 0; 177 158 178 - return sw->set(sw, orientation); 159 + sw_dev = sw->sw_dev; 160 + 161 + return sw_dev->set(sw_dev, orientation); 179 162 } 180 163 EXPORT_SYMBOL_GPL(typec_switch_set); 181 164 182 165 /** 183 166 * typec_switch_unregister - Unregister USB Type-C orientation switch 184 - * @sw: USB Type-C orientation switch 167 + * @sw_dev: USB Type-C orientation switch 185 168 * 186 169 * Unregister switch that was registered with typec_switch_register(). 187 170 */ 188 - void typec_switch_unregister(struct typec_switch *sw) 171 + void typec_switch_unregister(struct typec_switch_dev *sw_dev) 189 172 { 190 - if (!IS_ERR_OR_NULL(sw)) 191 - device_unregister(&sw->dev); 173 + if (!IS_ERR_OR_NULL(sw_dev)) 174 + device_unregister(&sw_dev->dev); 192 175 } 193 176 EXPORT_SYMBOL_GPL(typec_switch_unregister); 194 177 195 - void typec_switch_set_drvdata(struct typec_switch *sw, void *data) 178 + void typec_switch_set_drvdata(struct typec_switch_dev *sw_dev, void *data) 196 179 { 197 - dev_set_drvdata(&sw->dev, data); 180 + dev_set_drvdata(&sw_dev->dev, data); 198 181 } 199 182 EXPORT_SYMBOL_GPL(typec_switch_set_drvdata); 200 183 201 - void *typec_switch_get_drvdata(struct typec_switch *sw) 184 + void *typec_switch_get_drvdata(struct typec_switch_dev *sw_dev) 202 185 { 203 - return dev_get_drvdata(&sw->dev); 186 + return dev_get_drvdata(&sw_dev->dev); 204 187 } 205 188 EXPORT_SYMBOL_GPL(typec_switch_get_drvdata); 206 189 207 190 /* ------------------------------------------------------------------------- */ 208 191 192 + struct typec_mux { 193 + struct typec_mux_dev *mux_dev; 194 + }; 195 + 209 196 static int mux_fwnode_match(struct device *dev, const void *fwnode) 210 197 { 211 - if (!is_typec_mux(dev)) 198 + if (!is_typec_mux_dev(dev)) 212 199 return 0; 213 200 214 201 return dev_fwnode(dev) == fwnode; ··· 278 249 dev = class_find_device(&typec_mux_class, NULL, fwnode, 279 250 mux_fwnode_match); 280 251 281 - return dev ? to_typec_mux(dev) : ERR_PTR(-EPROBE_DEFER); 252 + return dev ? to_typec_mux_dev(dev) : ERR_PTR(-EPROBE_DEFER); 282 253 } 283 254 284 255 /** ··· 294 265 struct typec_mux *fwnode_typec_mux_get(struct fwnode_handle *fwnode, 295 266 const struct typec_altmode_desc *desc) 296 267 { 268 + struct typec_mux_dev *mux_dev; 297 269 struct typec_mux *mux; 298 270 299 - mux = fwnode_connection_find_match(fwnode, "mode-switch", (void *)desc, 300 - typec_mux_match); 301 - if (!IS_ERR_OR_NULL(mux)) 302 - WARN_ON(!try_module_get(mux->dev.parent->driver->owner)); 271 + mux = kzalloc(sizeof(*mux), GFP_KERNEL); 272 + if (!mux) 273 + return ERR_PTR(-ENOMEM); 274 + 275 + mux_dev = fwnode_connection_find_match(fwnode, "mode-switch", (void *)desc, 276 + typec_mux_match); 277 + if (IS_ERR_OR_NULL(mux_dev)) { 278 + kfree(mux); 279 + return ERR_CAST(mux_dev); 280 + } 281 + 282 + WARN_ON(!try_module_get(mux_dev->dev.parent->driver->owner)); 283 + 284 + mux->mux_dev = mux_dev; 303 285 304 286 return mux; 305 287 } ··· 324 284 */ 325 285 void typec_mux_put(struct typec_mux *mux) 326 286 { 327 - if (!IS_ERR_OR_NULL(mux)) { 328 - module_put(mux->dev.parent->driver->owner); 329 - put_device(&mux->dev); 330 - } 287 + struct typec_mux_dev *mux_dev; 288 + 289 + if (IS_ERR_OR_NULL(mux)) 290 + return; 291 + 292 + mux_dev = mux->mux_dev; 293 + module_put(mux_dev->dev.parent->driver->owner); 294 + put_device(&mux_dev->dev); 295 + kfree(mux); 331 296 } 332 297 EXPORT_SYMBOL_GPL(typec_mux_put); 333 298 334 299 int typec_mux_set(struct typec_mux *mux, struct typec_mux_state *state) 335 300 { 301 + struct typec_mux_dev *mux_dev; 302 + 336 303 if (IS_ERR_OR_NULL(mux)) 337 304 return 0; 338 305 339 - return mux->set(mux, state); 306 + mux_dev = mux->mux_dev; 307 + 308 + return mux_dev->set(mux_dev, state); 340 309 } 341 310 EXPORT_SYMBOL_GPL(typec_mux_set); 342 311 343 312 static void typec_mux_release(struct device *dev) 344 313 { 345 - kfree(to_typec_mux(dev)); 314 + kfree(to_typec_mux_dev(dev)); 346 315 } 347 316 348 317 const struct device_type typec_mux_dev_type = { ··· 369 320 * the pins on the connector need to be reconfigured. This function registers 370 321 * multiplexer switches routing the pins on the connector. 371 322 */ 372 - struct typec_mux * 323 + struct typec_mux_dev * 373 324 typec_mux_register(struct device *parent, const struct typec_mux_desc *desc) 374 325 { 375 - struct typec_mux *mux; 326 + struct typec_mux_dev *mux_dev; 376 327 int ret; 377 328 378 329 if (!desc || !desc->set) 379 330 return ERR_PTR(-EINVAL); 380 331 381 - mux = kzalloc(sizeof(*mux), GFP_KERNEL); 382 - if (!mux) 332 + mux_dev = kzalloc(sizeof(*mux_dev), GFP_KERNEL); 333 + if (!mux_dev) 383 334 return ERR_PTR(-ENOMEM); 384 335 385 - mux->set = desc->set; 336 + mux_dev->set = desc->set; 386 337 387 - device_initialize(&mux->dev); 388 - mux->dev.parent = parent; 389 - mux->dev.fwnode = desc->fwnode; 390 - mux->dev.class = &typec_mux_class; 391 - mux->dev.type = &typec_mux_dev_type; 392 - mux->dev.driver_data = desc->drvdata; 393 - ret = dev_set_name(&mux->dev, "%s-mux", desc->name ? desc->name : dev_name(parent)); 338 + device_initialize(&mux_dev->dev); 339 + mux_dev->dev.parent = parent; 340 + mux_dev->dev.fwnode = desc->fwnode; 341 + mux_dev->dev.class = &typec_mux_class; 342 + mux_dev->dev.type = &typec_mux_dev_type; 343 + mux_dev->dev.driver_data = desc->drvdata; 344 + ret = dev_set_name(&mux_dev->dev, "%s-mux", desc->name ? desc->name : dev_name(parent)); 394 345 if (ret) { 395 - put_device(&mux->dev); 346 + put_device(&mux_dev->dev); 396 347 return ERR_PTR(ret); 397 348 } 398 349 399 - ret = device_add(&mux->dev); 350 + ret = device_add(&mux_dev->dev); 400 351 if (ret) { 401 352 dev_err(parent, "failed to register mux (%d)\n", ret); 402 - put_device(&mux->dev); 353 + put_device(&mux_dev->dev); 403 354 return ERR_PTR(ret); 404 355 } 405 356 406 - return mux; 357 + return mux_dev; 407 358 } 408 359 EXPORT_SYMBOL_GPL(typec_mux_register); 409 360 410 361 /** 411 362 * typec_mux_unregister - Unregister Multiplexer Switch 412 - * @mux: USB Type-C Connector Multiplexer/DeMultiplexer 363 + * @mux_dev: USB Type-C Connector Multiplexer/DeMultiplexer 413 364 * 414 365 * Unregister mux that was registered with typec_mux_register(). 415 366 */ 416 - void typec_mux_unregister(struct typec_mux *mux) 367 + void typec_mux_unregister(struct typec_mux_dev *mux_dev) 417 368 { 418 - if (!IS_ERR_OR_NULL(mux)) 419 - device_unregister(&mux->dev); 369 + if (!IS_ERR_OR_NULL(mux_dev)) 370 + device_unregister(&mux_dev->dev); 420 371 } 421 372 EXPORT_SYMBOL_GPL(typec_mux_unregister); 422 373 423 - void typec_mux_set_drvdata(struct typec_mux *mux, void *data) 374 + void typec_mux_set_drvdata(struct typec_mux_dev *mux_dev, void *data) 424 375 { 425 - dev_set_drvdata(&mux->dev, data); 376 + dev_set_drvdata(&mux_dev->dev, data); 426 377 } 427 378 EXPORT_SYMBOL_GPL(typec_mux_set_drvdata); 428 379 429 - void *typec_mux_get_drvdata(struct typec_mux *mux) 380 + void *typec_mux_get_drvdata(struct typec_mux_dev *mux_dev) 430 381 { 431 - return dev_get_drvdata(&mux->dev); 382 + return dev_get_drvdata(&mux_dev->dev); 432 383 } 433 384 EXPORT_SYMBOL_GPL(typec_mux_get_drvdata); 434 385
+6 -6
drivers/usb/typec/mux.h
··· 5 5 6 6 #include <linux/usb/typec_mux.h> 7 7 8 - struct typec_switch { 8 + struct typec_switch_dev { 9 9 struct device dev; 10 10 typec_switch_set_fn_t set; 11 11 }; 12 12 13 - struct typec_mux { 13 + struct typec_mux_dev { 14 14 struct device dev; 15 15 typec_mux_set_fn_t set; 16 16 }; 17 17 18 - #define to_typec_switch(_dev_) container_of(_dev_, struct typec_switch, dev) 19 - #define to_typec_mux(_dev_) container_of(_dev_, struct typec_mux, dev) 18 + #define to_typec_switch_dev(_dev_) container_of(_dev_, struct typec_switch_dev, dev) 19 + #define to_typec_mux_dev(_dev_) container_of(_dev_, struct typec_mux_dev, dev) 20 20 21 21 extern const struct device_type typec_switch_dev_type; 22 22 extern const struct device_type typec_mux_dev_type; 23 23 24 - #define is_typec_switch(dev) ((dev)->type == &typec_switch_dev_type) 25 - #define is_typec_mux(dev) ((dev)->type == &typec_mux_dev_type) 24 + #define is_typec_switch_dev(dev) ((dev)->type == &typec_switch_dev_type) 25 + #define is_typec_mux_dev(dev) ((dev)->type == &typec_mux_dev_type) 26 26 27 27 #endif /* __USB_TYPEC_MUX__ */
+4 -4
drivers/usb/typec/mux/intel_pmc_mux.c
··· 121 121 int num; 122 122 u32 iom_status; 123 123 struct pmc_usb *pmc; 124 - struct typec_mux *typec_mux; 125 - struct typec_switch *typec_sw; 124 + struct typec_mux_dev *typec_mux; 125 + struct typec_switch_dev *typec_sw; 126 126 struct usb_role_switch *usb_sw; 127 127 128 128 enum typec_orientation orientation; ··· 433 433 } 434 434 435 435 static int 436 - pmc_usb_mux_set(struct typec_mux *mux, struct typec_mux_state *state) 436 + pmc_usb_mux_set(struct typec_mux_dev *mux, struct typec_mux_state *state) 437 437 { 438 438 struct pmc_usb_port *port = typec_mux_get_drvdata(mux); 439 439 ··· 469 469 return -EOPNOTSUPP; 470 470 } 471 471 472 - static int pmc_usb_set_orientation(struct typec_switch *sw, 472 + static int pmc_usb_set_orientation(struct typec_switch_dev *sw, 473 473 enum typec_orientation orientation) 474 474 { 475 475 struct pmc_usb_port *port = typec_switch_get_drvdata(sw);
+4 -4
drivers/usb/typec/mux/pi3usb30532.c
··· 23 23 struct pi3usb30532 { 24 24 struct i2c_client *client; 25 25 struct mutex lock; /* protects the cached conf register */ 26 - struct typec_switch *sw; 27 - struct typec_mux *mux; 26 + struct typec_switch_dev *sw; 27 + struct typec_mux_dev *mux; 28 28 u8 conf; 29 29 }; 30 30 ··· 45 45 return 0; 46 46 } 47 47 48 - static int pi3usb30532_sw_set(struct typec_switch *sw, 48 + static int pi3usb30532_sw_set(struct typec_switch_dev *sw, 49 49 enum typec_orientation orientation) 50 50 { 51 51 struct pi3usb30532 *pi = typec_switch_get_drvdata(sw); ··· 74 74 } 75 75 76 76 static int 77 - pi3usb30532_mux_set(struct typec_mux *mux, struct typec_mux_state *state) 77 + pi3usb30532_mux_set(struct typec_mux_dev *mux, struct typec_mux_state *state) 78 78 { 79 79 struct pi3usb30532 *pi = typec_mux_get_drvdata(mux); 80 80 u8 new_conf;
+12 -10
include/linux/usb/typec_mux.h
··· 8 8 9 9 struct device; 10 10 struct typec_mux; 11 + struct typec_mux_dev; 11 12 struct typec_switch; 13 + struct typec_switch_dev; 12 14 struct typec_altmode; 13 15 struct fwnode_handle; 14 16 15 - typedef int (*typec_switch_set_fn_t)(struct typec_switch *sw, 17 + typedef int (*typec_switch_set_fn_t)(struct typec_switch_dev *sw, 16 18 enum typec_orientation orientation); 17 19 18 20 struct typec_switch_desc { ··· 34 32 return fwnode_typec_switch_get(dev_fwnode(dev)); 35 33 } 36 34 37 - struct typec_switch * 35 + struct typec_switch_dev * 38 36 typec_switch_register(struct device *parent, 39 37 const struct typec_switch_desc *desc); 40 - void typec_switch_unregister(struct typec_switch *sw); 38 + void typec_switch_unregister(struct typec_switch_dev *sw); 41 39 42 - void typec_switch_set_drvdata(struct typec_switch *sw, void *data); 43 - void *typec_switch_get_drvdata(struct typec_switch *sw); 40 + void typec_switch_set_drvdata(struct typec_switch_dev *sw, void *data); 41 + void *typec_switch_get_drvdata(struct typec_switch_dev *sw); 44 42 45 43 struct typec_mux_state { 46 44 struct typec_altmode *alt; ··· 48 46 void *data; 49 47 }; 50 48 51 - typedef int (*typec_mux_set_fn_t)(struct typec_mux *mux, 49 + typedef int (*typec_mux_set_fn_t)(struct typec_mux_dev *mux, 52 50 struct typec_mux_state *state); 53 51 54 52 struct typec_mux_desc { ··· 69 67 return fwnode_typec_mux_get(dev_fwnode(dev), desc); 70 68 } 71 69 72 - struct typec_mux * 70 + struct typec_mux_dev * 73 71 typec_mux_register(struct device *parent, const struct typec_mux_desc *desc); 74 - void typec_mux_unregister(struct typec_mux *mux); 72 + void typec_mux_unregister(struct typec_mux_dev *mux); 75 73 76 - void typec_mux_set_drvdata(struct typec_mux *mux, void *data); 77 - void *typec_mux_get_drvdata(struct typec_mux *mux); 74 + void typec_mux_set_drvdata(struct typec_mux_dev *mux, void *data); 75 + void *typec_mux_get_drvdata(struct typec_mux_dev *mux); 78 76 79 77 #endif /* __USB_TYPEC_MUX */