thunderbolt: Skip discovery also in USB4 v2 host
authorMika Westerberg <mika.westerberg@linux.intel.com>
Fri, 2 Feb 2024 14:38:19 +0000 (16:38 +0200)
committerMika Westerberg <mika.westerberg@linux.intel.com>
Tue, 13 Feb 2024 09:08:36 +0000 (11:08 +0200)
If the host router is reset, there is no point running discovery as the
links are down. Furthermore this prevents CL-state enabling. For this
reason skip discovery in USB4 v2 host the same way we do with USB4 v1.

Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
drivers/thunderbolt/nhi.c
drivers/thunderbolt/tb.c

index e8a4623dc531979d5acbbd6fdf90284e89c0f77e..91e26b982b0bf0cdb3ba75d9ae763aa3bfa486ba 100644 (file)
@@ -1221,7 +1221,7 @@ static void nhi_check_iommu(struct tb_nhi *nhi)
                str_enabled_disabled(port_ok));
 }
 
-static bool nhi_reset(struct tb_nhi *nhi)
+static void nhi_reset(struct tb_nhi *nhi)
 {
        ktime_t timeout;
        u32 val;
@@ -1229,11 +1229,11 @@ static bool nhi_reset(struct tb_nhi *nhi)
        val = ioread32(nhi->iobase + REG_CAPS);
        /* Reset only v2 and later routers */
        if (FIELD_GET(REG_CAPS_VERSION_MASK, val) < REG_CAPS_VERSION_2)
-               return false;
+               return;
 
        if (!host_reset) {
                dev_dbg(&nhi->pdev->dev, "skipping host router reset\n");
-               return false;
+               return;
        }
 
        iowrite32(REG_RESET_HRR, nhi->iobase + REG_RESET);
@@ -1244,14 +1244,12 @@ static bool nhi_reset(struct tb_nhi *nhi)
                val = ioread32(nhi->iobase + REG_RESET);
                if (!(val & REG_RESET_HRR)) {
                        dev_warn(&nhi->pdev->dev, "host router reset successful\n");
-                       return true;
+                       return;
                }
                usleep_range(10, 20);
        } while (ktime_before(ktime_get(), timeout));
 
        dev_warn(&nhi->pdev->dev, "timeout resetting host router\n");
-
-       return false;
 }
 
 static int nhi_init_msi(struct tb_nhi *nhi)
@@ -1333,7 +1331,6 @@ static int nhi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        struct device *dev = &pdev->dev;
        struct tb_nhi *nhi;
        struct tb *tb;
-       bool reset;
        int res;
 
        if (!nhi_imr_valid(pdev))
@@ -1367,12 +1364,7 @@ static int nhi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 
        nhi_check_quirks(nhi);
        nhi_check_iommu(nhi);
-
-       /*
-        * Only USB4 v2 hosts support host reset so if we already did
-        * that then don't do it again when the domain is initialized.
-        */
-       reset = nhi_reset(nhi) ? false : host_reset;
+       nhi_reset(nhi);
 
        res = nhi_init_msi(nhi);
        if (res)
@@ -1399,7 +1391,7 @@ static int nhi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 
        dev_dbg(dev, "NHI initialized, starting thunderbolt\n");
 
-       res = tb_domain_add(tb, reset);
+       res = tb_domain_add(tb, host_reset);
        if (res) {
                /*
                 * At this point the RX/TX rings might already have been
index f127088b6ebd1c139cf655c51a6ec71cd7455140..64dd22e1f5b2940d4476d9d267c304e139c198a1 100644 (file)
@@ -2584,6 +2584,7 @@ static int tb_scan_finalize_switch(struct device *dev, void *data)
 static int tb_start(struct tb *tb, bool reset)
 {
        struct tb_cm *tcm = tb_priv(tb);
+       bool discover = true;
        int ret;
 
        tb->root_switch = tb_switch_alloc(tb, &tb->dev, 0);
@@ -2629,9 +2630,13 @@ static int tb_start(struct tb *tb, bool reset)
         * reset the ports to handle it as new hotplug for USB4 v1
         * routers (for USB4 v2 and beyond we already do host reset).
         */
-       if (reset && usb4_switch_version(tb->root_switch) == 1) {
-               tb_switch_reset(tb->root_switch);
-       } else {
+       if (reset && tb_switch_is_usb4(tb->root_switch)) {
+               discover = false;
+               if (usb4_switch_version(tb->root_switch) == 1)
+                       tb_switch_reset(tb->root_switch);
+       }
+
+       if (discover) {
                /* Full scan to discover devices added before the driver was loaded. */
                tb_scan_switch(tb->root_switch);
                /* Find out tunnels created by the boot firmware */