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

Configure Feed

Select the types of activity you want to include in your feed.

usb: typec: Set the bus also for the port and plug altmodes

The port and plug altmodes can't be bound to the altmode
drivers because the altmode drivers are meant for partner
communication using the VDM (vendor defined messages), but
they can still be part of the bus. The bus will make sure
that the normal bus notifications are available also with
the port altmodes.

The previously used common device type for all alternate
modes is replaced with separate dedicated device types for
port, plug, and partner alternate modes.

Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Chaoyi Chen <chaoyi.chen@rock-chips.com>
Link: https://patch.msgid.link/20251208015500.94-2-kernel@airkyi.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Heikki Krogerus and committed by
Greg Kroah-Hartman
67ab4542 36723c6c

+51 -14
+23 -1
drivers/usb/typec/bus.c
··· 445 445 &dev_attr_description.attr, 446 446 NULL 447 447 }; 448 - ATTRIBUTE_GROUPS(typec); 448 + 449 + static umode_t typec_is_visible(struct kobject *kobj, struct attribute *attr, int n) 450 + { 451 + if (is_typec_partner_altmode(kobj_to_dev(kobj))) 452 + return attr->mode; 453 + return 0; 454 + } 455 + 456 + static const struct attribute_group typec_group = { 457 + .is_visible = typec_is_visible, 458 + .attrs = typec_attrs, 459 + }; 460 + 461 + static const struct attribute_group *typec_groups[] = { 462 + &typec_group, 463 + NULL 464 + }; 449 465 450 466 static int typec_match(struct device *dev, const struct device_driver *driver) 451 467 { 452 468 const struct typec_altmode_driver *drv = to_altmode_driver(driver); 453 469 struct typec_altmode *altmode = to_typec_altmode(dev); 454 470 const struct typec_device_id *id; 471 + 472 + if (!is_typec_partner_altmode(dev)) 473 + return 0; 455 474 456 475 for (id = drv->id_table; id->svid; id++) 457 476 if (id->svid == altmode->svid) ··· 481 462 static int typec_uevent(const struct device *dev, struct kobj_uevent_env *env) 482 463 { 483 464 const struct typec_altmode *altmode = to_typec_altmode(dev); 465 + 466 + if (!is_typec_partner_altmode(dev)) 467 + return 0; 484 468 485 469 if (add_uevent_var(env, "SVID=%04X", altmode->svid)) 486 470 return -ENOMEM;
+6 -2
drivers/usb/typec/bus.h
··· 29 29 #define to_altmode(d) container_of(d, struct altmode, adev) 30 30 31 31 extern const struct bus_type typec_bus; 32 - extern const struct device_type typec_altmode_dev_type; 32 + extern const struct device_type typec_port_altmode_dev_type; 33 + extern const struct device_type typec_plug_altmode_dev_type; 34 + extern const struct device_type typec_partner_altmode_dev_type; 33 35 34 - #define is_typec_altmode(_dev_) (_dev_->type == &typec_altmode_dev_type) 36 + #define is_typec_port_altmode(dev) ((dev)->type == &typec_port_altmode_dev_type) 37 + #define is_typec_plug_altmode(dev) ((dev)->type == &typec_plug_altmode_dev_type) 38 + #define is_typec_partner_altmode(dev) ((dev)->type == &typec_partner_altmode_dev_type) 35 39 36 40 #endif /* __USB_TYPEC_ALTMODE_H__ */
+22 -11
drivers/usb/typec/class.c
··· 235 235 struct typec_altmode *adev = to_typec_altmode(dev); 236 236 const struct typec_device_id *id = data; 237 237 238 - if (!is_typec_altmode(dev)) 238 + if (!is_typec_port_altmode(dev)) 239 239 return 0; 240 240 241 241 return (adev->svid == id->svid); ··· 532 532 kfree(alt); 533 533 } 534 534 535 - const struct device_type typec_altmode_dev_type = { 536 - .name = "typec_alternate_mode", 535 + const struct device_type typec_port_altmode_dev_type = { 536 + .name = "typec_port_alternate_mode", 537 + .groups = typec_altmode_groups, 538 + .release = typec_altmode_release, 539 + }; 540 + 541 + const struct device_type typec_plug_altmode_dev_type = { 542 + .name = "typec_plug_alternate_mode", 543 + .groups = typec_altmode_groups, 544 + .release = typec_altmode_release, 545 + }; 546 + 547 + const struct device_type typec_partner_altmode_dev_type = { 548 + .name = "typec_partner_alternate_mode", 537 549 .groups = typec_altmode_groups, 538 550 .release = typec_altmode_release, 539 551 }; 540 552 541 553 static struct typec_altmode * 542 554 typec_register_altmode(struct device *parent, 543 - const struct typec_altmode_desc *desc) 555 + const struct typec_altmode_desc *desc, 556 + const struct device_type *type) 544 557 { 545 558 unsigned int id = altmode_id_get(parent); 546 559 bool is_port = is_typec_port(parent); ··· 588 575 589 576 alt->adev.dev.parent = parent; 590 577 alt->adev.dev.groups = alt->groups; 591 - alt->adev.dev.type = &typec_altmode_dev_type; 578 + alt->adev.dev.type = type; 592 579 dev_set_name(&alt->adev.dev, "%s.%u", dev_name(parent), id); 593 580 594 581 get_device(alt->adev.dev.parent); ··· 597 584 if (!is_port) 598 585 typec_altmode_set_partner(alt); 599 586 600 - /* The partners are bind to drivers */ 601 - if (is_typec_partner(parent)) 602 - alt->adev.dev.bus = &typec_bus; 587 + alt->adev.dev.bus = &typec_bus; 603 588 604 589 /* Plug alt modes need a class to generate udev events. */ 605 590 if (is_typec_plug(parent)) ··· 974 963 typec_partner_register_altmode(struct typec_partner *partner, 975 964 const struct typec_altmode_desc *desc) 976 965 { 977 - return typec_register_altmode(&partner->dev, desc); 966 + return typec_register_altmode(&partner->dev, desc, &typec_partner_altmode_dev_type); 978 967 } 979 968 EXPORT_SYMBOL_GPL(typec_partner_register_altmode); 980 969 ··· 1204 1193 typec_plug_register_altmode(struct typec_plug *plug, 1205 1194 const struct typec_altmode_desc *desc) 1206 1195 { 1207 - return typec_register_altmode(&plug->dev, desc); 1196 + return typec_register_altmode(&plug->dev, desc, &typec_plug_altmode_dev_type); 1208 1197 } 1209 1198 EXPORT_SYMBOL_GPL(typec_plug_register_altmode); 1210 1199 ··· 2504 2493 return ERR_CAST(retimer); 2505 2494 } 2506 2495 2507 - adev = typec_register_altmode(&port->dev, desc); 2496 + adev = typec_register_altmode(&port->dev, desc, &typec_port_altmode_dev_type); 2508 2497 if (IS_ERR(adev)) { 2509 2498 typec_retimer_put(retimer); 2510 2499 typec_mux_put(mux);