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

usb: typec: update partner power delivery support with opmode

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@linux.intel.com>
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Heikki Krogerus and committed by
Greg Kroah-Hartman
7ee4ce6e e6b20121

+19
+19
drivers/usb/typec/typec.c
··· 1124 1124 } 1125 1125 EXPORT_SYMBOL_GPL(typec_set_vconn_role); 1126 1126 1127 + static int partner_match(struct device *dev, void *data) 1128 + { 1129 + return is_typec_partner(dev); 1130 + } 1131 + 1127 1132 /** 1128 1133 * typec_set_pwr_opmode - Report changed power operation mode 1129 1134 * @port: The USB Type-C Port where the mode was changed ··· 1142 1137 void typec_set_pwr_opmode(struct typec_port *port, 1143 1138 enum typec_pwr_opmode opmode) 1144 1139 { 1140 + struct device *partner_dev; 1141 + 1145 1142 if (port->pwr_opmode == opmode) 1146 1143 return; 1147 1144 1148 1145 port->pwr_opmode = opmode; 1149 1146 sysfs_notify(&port->dev.kobj, NULL, "power_operation_mode"); 1150 1147 kobject_uevent(&port->dev.kobj, KOBJ_CHANGE); 1148 + 1149 + partner_dev = device_find_child(&port->dev, NULL, partner_match); 1150 + if (partner_dev) { 1151 + struct typec_partner *partner = to_typec_partner(partner_dev); 1152 + 1153 + if (opmode == TYPEC_PWR_MODE_PD && !partner->usb_pd) { 1154 + partner->usb_pd = 1; 1155 + sysfs_notify(&partner_dev->kobj, NULL, 1156 + "supports_usb_power_delivery"); 1157 + } 1158 + put_device(partner_dev); 1159 + } 1151 1160 } 1152 1161 EXPORT_SYMBOL_GPL(typec_set_pwr_opmode); 1153 1162