diff options
Diffstat (limited to 'drivers/thunderbolt/nhi.c')
-rw-r--r-- | drivers/thunderbolt/nhi.c | 39 |
1 files changed, 31 insertions, 8 deletions
diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c index cfc622da4f83..a0386d1e3fc9 100644 --- a/drivers/thunderbolt/nhi.c +++ b/drivers/thunderbolt/nhi.c @@ -44,7 +44,7 @@ static int ring_interrupt_index(struct tb_ring *ring) return bit; } -/** +/* * ring_interrupt_active() - activate/deactivate interrupts for a single ring * * ring->nhi->lock must be held. @@ -105,7 +105,7 @@ static void ring_interrupt_active(struct tb_ring *ring, bool active) iowrite32(new, ring->nhi->iobase + reg); } -/** +/* * nhi_disable_interrupts() - disable interrupts for all rings * * Use only during init and shutdown. @@ -182,7 +182,7 @@ static bool ring_empty(struct tb_ring *ring) return ring->head == ring->tail; } -/** +/* * ring_write_descriptors() - post frames from ring->queue to the controller * * ring->lock is held. @@ -212,7 +212,7 @@ static void ring_write_descriptors(struct tb_ring *ring) } } -/** +/* * ring_work() - progress completed frames * * If the ring is shutting down then all frames are marked as canceled and @@ -592,6 +592,7 @@ EXPORT_SYMBOL_GPL(tb_ring_alloc_rx); /** * tb_ring_start() - enable a ring + * @ring: Ring to start * * Must not be invoked in parallel with tb_ring_stop(). */ @@ -667,6 +668,7 @@ EXPORT_SYMBOL_GPL(tb_ring_start); /** * tb_ring_stop() - shutdown a ring + * @ring: Ring to stop * * Must not be invoked from a callback. * @@ -754,7 +756,7 @@ void tb_ring_free(struct tb_ring *ring) dev_dbg(&ring->nhi->pdev->dev, "freeing %s %d\n", RING_TYPE(ring), ring->hop); - /** + /* * ring->work can no longer be scheduled (it is scheduled only * by nhi_interrupt_work, ring_stop and ring_msix). Wait for it * to finish before freeing the ring. @@ -1188,6 +1190,29 @@ static void tb_apple_add_links(struct tb_nhi *nhi) } } +static struct tb *nhi_select_cm(struct tb_nhi *nhi) +{ + struct tb *tb; + + /* + * USB4 case is simple. If we got control of any of the + * capabilities, we use software CM. + */ + if (tb_acpi_is_native()) + return tb_probe(nhi); + + /* + * Either firmware based CM is running (we did not get control + * from the firmware) or this is pre-USB4 PC so try first + * firmware CM and then fallback to software CM. + */ + tb = icm_probe(nhi); + if (!tb) + tb = tb_probe(nhi); + + return tb; +} + static int nhi_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct tb_nhi *nhi; @@ -1256,9 +1281,7 @@ static int nhi_probe(struct pci_dev *pdev, const struct pci_device_id *id) tb_apple_add_links(nhi); tb_acpi_add_links(nhi); - tb = icm_probe(nhi); - if (!tb) - tb = tb_probe(nhi); + tb = nhi_select_cm(nhi); if (!tb) { dev_err(&nhi->pdev->dev, "failed to determine connection manager, aborting\n"); |