@@ -2772,6 +2772,26 @@ static void tb_switch_credits_init(struct tb_switch *sw)
tb_sw_info(sw, "failed to determine preferred buffer allocation, using defaults\n");
}
+static int tb_switch_port_hotplug_enable(struct tb_switch *sw)
+{
+ struct tb_port *port;
+
+ if (tb_switch_is_icm(sw))
+ return 0;
+
+ tb_switch_for_each_port(sw, port) {
+ int res;
+
+ if (!port->cap_usb4)
+ continue;
+
+ res = usb4_port_hotplug_enable(port);
+ if (res)
+ return res;
+ }
+ return 0;
+}
+
/**
* tb_switch_add() - Add a switch to the domain
* @sw: Switch to add
@@ -2841,6 +2861,10 @@ int tb_switch_add(struct tb_switch *sw)
return ret;
}
+ ret = tb_switch_port_hotplug_enable(sw);
+ if (ret)
+ return ret;
+
ret = device_add(&sw->dev);
if (ret) {
dev_err(&sw->dev, "failed to add device: %d\n", ret);
@@ -1184,6 +1184,7 @@ int usb4_switch_add_ports(struct tb_switch *sw);
void usb4_switch_remove_ports(struct tb_switch *sw);
int usb4_port_unlock(struct tb_port *port);
+int usb4_port_hotplug_enable(struct tb_port *port);
int usb4_port_configure(struct tb_port *port);
void usb4_port_unconfigure(struct tb_port *port);
int usb4_port_configure_xdomain(struct tb_port *port);
@@ -308,6 +308,7 @@ struct tb_regs_port_header {
#define ADP_CS_5 0x05
#define ADP_CS_5_LCA_MASK GENMASK(28, 22)
#define ADP_CS_5_LCA_SHIFT 22
+#define ADP_CS_5_DHP BIT(31)
/* TMU adapter registers */
#define TMU_ADP_CS_3 0x03
@@ -1046,6 +1046,26 @@ int usb4_port_unlock(struct tb_port *port)
return tb_port_write(port, &val, TB_CFG_PORT, ADP_CS_4, 1);
}
+/**
+ * usb4_port_hotplug_enable() - Enables hotplug for a port
+ * @port: USB4 port to operate on
+ *
+ * Enables hot plug events on a given port. This is only intended
+ * to be used on lane, DP-IN, and DP-OUT adapters.
+ */
+int usb4_port_hotplug_enable(struct tb_port *port)
+{
+ int ret;
+ u32 val;
+
+ ret = tb_port_read(port, &val, TB_CFG_PORT, ADP_CS_5, 1);
+ if (ret)
+ return ret;
+
+ val &= ~ADP_CS_5_DHP;
+ return tb_port_write(port, &val, TB_CFG_PORT, ADP_CS_5, 1);
+}
+
static int usb4_port_set_configured(struct tb_port *port, bool configured)
{
int ret;