summaryrefslogtreecommitdiff
path: root/drivers/thunderbolt/icm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/thunderbolt/icm.c')
-rw-r--r--drivers/thunderbolt/icm.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/drivers/thunderbolt/icm.c b/drivers/thunderbolt/icm.c
index ab02d13f40b7..182226023acb 100644
--- a/drivers/thunderbolt/icm.c
+++ b/drivers/thunderbolt/icm.c
@@ -383,6 +383,15 @@ static void remove_switch(struct tb_switch *sw)
tb_switch_remove(sw);
}
+static void remove_xdomain(struct tb_xdomain *xd)
+{
+ struct tb_switch *sw;
+
+ sw = tb_to_switch(xd->dev.parent);
+ tb_port_at(xd->route, sw)->xdomain = NULL;
+ tb_xdomain_remove(xd);
+}
+
static void
icm_fr_device_connected(struct tb *tb, const struct icm_pkg_header *hdr)
{
@@ -391,6 +400,7 @@ icm_fr_device_connected(struct tb *tb, const struct icm_pkg_header *hdr)
struct tb_switch *sw, *parent_sw;
struct icm *icm = tb_priv(tb);
bool authorized = false;
+ struct tb_xdomain *xd;
u8 link, depth;
u64 route;
int ret;
@@ -467,6 +477,13 @@ icm_fr_device_connected(struct tb *tb, const struct icm_pkg_header *hdr)
tb_switch_put(sw);
}
+ /* Remove existing XDomain connection if found */
+ xd = tb_xdomain_find_by_link_depth(tb, link, depth);
+ if (xd) {
+ remove_xdomain(xd);
+ tb_xdomain_put(xd);
+ }
+
parent_sw = tb_switch_find_by_link_depth(tb, link, depth - 1);
if (!parent_sw) {
tb_err(tb, "failed to find parent switch for %u.%u\n",
@@ -529,15 +546,6 @@ icm_fr_device_disconnected(struct tb *tb, const struct icm_pkg_header *hdr)
tb_switch_put(sw);
}
-static void remove_xdomain(struct tb_xdomain *xd)
-{
- struct tb_switch *sw;
-
- sw = tb_to_switch(xd->dev.parent);
- tb_port_at(xd->route, sw)->xdomain = NULL;
- tb_xdomain_remove(xd);
-}
-
static void
icm_fr_xdomain_connected(struct tb *tb, const struct icm_pkg_header *hdr)
{