static void ucsi_partner_change(struct ucsi_connector *con)
 {
+       enum usb_role u_role = USB_ROLE_NONE;
        int ret;
 
        if (!con->partner)
 
        switch (UCSI_CONSTAT_PARTNER_TYPE(con->status.flags)) {
        case UCSI_CONSTAT_PARTNER_TYPE_UFP:
-       case UCSI_CONSTAT_PARTNER_TYPE_CABLE:
        case UCSI_CONSTAT_PARTNER_TYPE_CABLE_AND_UFP:
+               u_role = USB_ROLE_HOST;
+               fallthrough;
+       case UCSI_CONSTAT_PARTNER_TYPE_CABLE:
                typec_set_data_role(con->port, TYPEC_HOST);
                break;
        case UCSI_CONSTAT_PARTNER_TYPE_DFP:
+               u_role = USB_ROLE_DEVICE;
                typec_set_data_role(con->port, TYPEC_DEVICE);
                break;
        default:
        if (!completion_done(&con->complete))
                complete(&con->complete);
 
+       /* Only notify USB controller if partner supports USB data */
+       if (!(UCSI_CONSTAT_PARTNER_FLAGS(con->status.flags) & UCSI_CONSTAT_PARTNER_FLAG_USB))
+               u_role = USB_ROLE_NONE;
+
+       ret = usb_role_switch_set_role(con->usb_role_sw, u_role);
+       if (ret)
+               dev_err(con->ucsi->dev, "con:%d: failed to set usb role:%d\n",
+                       con->num, u_role);
+
        /* Can't rely on Partner Flags field. Always checking the alt modes. */
        ret = ucsi_register_altmodes(con, UCSI_RECIPIENT_SOP);
        if (ret)
        struct ucsi_connector_status pre_ack_status;
        struct ucsi_connector_status post_ack_status;
        enum typec_role role;
+       enum usb_role u_role = USB_ROLE_NONE;
        u16 inferred_changes;
        u16 changed_flags;
        u64 command;
 
                switch (UCSI_CONSTAT_PARTNER_TYPE(con->status.flags)) {
                case UCSI_CONSTAT_PARTNER_TYPE_UFP:
-               case UCSI_CONSTAT_PARTNER_TYPE_CABLE:
                case UCSI_CONSTAT_PARTNER_TYPE_CABLE_AND_UFP:
+                       u_role = USB_ROLE_HOST;
+                       fallthrough;
+               case UCSI_CONSTAT_PARTNER_TYPE_CABLE:
                        typec_set_data_role(con->port, TYPEC_HOST);
                        break;
                case UCSI_CONSTAT_PARTNER_TYPE_DFP:
+                       u_role = USB_ROLE_DEVICE;
                        typec_set_data_role(con->port, TYPEC_DEVICE);
                        break;
                default:
                        ucsi_unregister_partner(con);
 
                ucsi_port_psy_changed(con);
+
+               /* Only notify USB controller if partner supports USB data */
+               if (!(UCSI_CONSTAT_PARTNER_FLAGS(con->status.flags) &
+                               UCSI_CONSTAT_PARTNER_FLAG_USB))
+                       u_role = USB_ROLE_NONE;
+
+               ret = usb_role_switch_set_role(con->usb_role_sw, u_role);
+               if (ret)
+                       dev_err(ucsi->dev, "con:%d: failed to set usb role:%d\n",
+                               con->num, u_role);
        }
 
        if (con->status.change & UCSI_CONSTAT_PARTNER_CHANGE)
        struct ucsi_connector *con = &ucsi->connector[index];
        struct typec_capability *cap = &con->typec_cap;
        enum typec_accessory *accessory = cap->accessory;
+       enum usb_role u_role = USB_ROLE_NONE;
        u64 command;
        int ret;
 
 
        switch (UCSI_CONSTAT_PARTNER_TYPE(con->status.flags)) {
        case UCSI_CONSTAT_PARTNER_TYPE_UFP:
-       case UCSI_CONSTAT_PARTNER_TYPE_CABLE:
        case UCSI_CONSTAT_PARTNER_TYPE_CABLE_AND_UFP:
+               u_role = USB_ROLE_HOST;
+               fallthrough;
+       case UCSI_CONSTAT_PARTNER_TYPE_CABLE:
                typec_set_data_role(con->port, TYPEC_HOST);
                break;
        case UCSI_CONSTAT_PARTNER_TYPE_DFP:
+               u_role = USB_ROLE_DEVICE;
                typec_set_data_role(con->port, TYPEC_DEVICE);
                break;
        default:
                ucsi_port_psy_changed(con);
        }
 
+       con->usb_role_sw = fwnode_usb_role_switch_get(cap->fwnode);
+       if (IS_ERR(con->usb_role_sw)) {
+               dev_err(ucsi->dev, "con%d: failed to get usb role switch\n",
+                       con->num);
+               con->usb_role_sw = NULL;
+       }
+
+       /* Only notify USB controller if partner supports USB data */
+       if (!(UCSI_CONSTAT_PARTNER_FLAGS(con->status.flags) & UCSI_CONSTAT_PARTNER_FLAG_USB))
+               u_role = USB_ROLE_NONE;
+
+       ret = usb_role_switch_set_role(con->usb_role_sw, u_role);
+       if (ret) {
+               dev_err(ucsi->dev, "con:%d: failed to set usb role:%d\n",
+                       con->num, u_role);
+               ret = 0;
+       }
+
        if (con->partner) {
                ret = ucsi_register_altmodes(con, UCSI_RECIPIENT_SOP);
                if (ret) {