usb: typec: tcpm: Do not disconnect link for self powered devices
[platform/kernel/linux-rpi.git] / drivers / usb / typec / tcpm / tcpm.c
index dbbd71f..ba6e5cd 100644 (file)
@@ -317,6 +317,9 @@ struct tcpm_port {
        /* Deadline in jiffies to exit src_try_wait state */
        unsigned long max_wait;
 
+       /* port belongs to a self powered device */
+       bool self_powered;
+
 #ifdef CONFIG_DEBUG_FS
        struct dentry *dentry;
        struct mutex logbuffer_lock;    /* log buffer access lock */
@@ -3254,7 +3257,8 @@ static void run_state_machine(struct tcpm_port *port)
        case SRC_HARD_RESET_VBUS_OFF:
                tcpm_set_vconn(port, true);
                tcpm_set_vbus(port, false);
-               tcpm_set_roles(port, false, TYPEC_SOURCE, TYPEC_HOST);
+               tcpm_set_roles(port, port->self_powered, TYPEC_SOURCE,
+                              TYPEC_HOST);
                tcpm_set_state(port, SRC_HARD_RESET_VBUS_ON, PD_T_SRC_RECOVER);
                break;
        case SRC_HARD_RESET_VBUS_ON:
@@ -3267,7 +3271,8 @@ static void run_state_machine(struct tcpm_port *port)
                memset(&port->pps_data, 0, sizeof(port->pps_data));
                tcpm_set_vconn(port, false);
                tcpm_set_charge(port, false);
-               tcpm_set_roles(port, false, TYPEC_SINK, TYPEC_DEVICE);
+               tcpm_set_roles(port, port->self_powered, TYPEC_SINK,
+                              TYPEC_DEVICE);
                /*
                 * VBUS may or may not toggle, depending on the adapter.
                 * If it doesn't toggle, transition to SNK_HARD_RESET_SINK_ON
@@ -4412,6 +4417,8 @@ sink:
                return -EINVAL;
        port->operating_snk_mw = mw / 1000;
 
+       port->self_powered = fwnode_property_read_bool(fwnode, "self-powered");
+
        return 0;
 }
 
@@ -4720,6 +4727,7 @@ static int tcpm_copy_caps(struct tcpm_port *port,
        port->typec_caps.prefer_role = tcfg->default_role;
        port->typec_caps.type = tcfg->type;
        port->typec_caps.data = tcfg->data;
+       port->self_powered = port->tcpc->config->self_powered;
 
        return 0;
 }