If USB PD contract is established after creation of the partner, the power delivery support attribute of the partner needs to be updated separately. This can be done in typec_set_pwr_opmode() by checking if the port has already partner and updating the value if it does. Signed-off-by: Heikki Krogerus <heikki.krogerus@xxxxxxxxxxxxxxx> --- drivers/usb/typec/typec.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/drivers/usb/typec/typec.c b/drivers/usb/typec/typec.c index 89e540bb7ff3..18076b44cf56 100644 --- a/drivers/usb/typec/typec.c +++ b/drivers/usb/typec/typec.c @@ -1123,6 +1123,11 @@ void typec_set_vconn_role(struct typec_port *port, enum typec_role role) } EXPORT_SYMBOL_GPL(typec_set_vconn_role); +static int partner_match(struct device *dev, void *data) +{ + return is_typec_partner(dev); +} + /** * typec_set_pwr_opmode - Report changed power operation mode * @port: The USB Type-C Port where the mode was changed @@ -1136,12 +1141,26 @@ EXPORT_SYMBOL_GPL(typec_set_vconn_role); void typec_set_pwr_opmode(struct typec_port *port, enum typec_pwr_opmode opmode) { + struct device *partner_dev; + if (port->pwr_opmode == opmode) return; port->pwr_opmode = opmode; sysfs_notify(&port->dev.kobj, NULL, "power_operation_mode"); kobject_uevent(&port->dev.kobj, KOBJ_CHANGE); + + partner_dev = device_find_child(&port->dev, NULL, partner_match); + if (partner_dev) { + struct typec_partner *partner = to_typec_partner(partner_dev); + + if (opmode == TYPEC_PWR_MODE_PD && !partner->usb_pd) { + partner->usb_pd = 1; + sysfs_notify(&partner_dev->kobj, NULL, + "supports_usb_power_delivery"); + } + put_device(partner_dev); + } } EXPORT_SYMBOL_GPL(typec_set_pwr_opmode); -- 2.11.0 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html