summaryrefslogtreecommitdiffstats
path: root/drivers/thunderbolt
diff options
context:
space:
mode:
authorMika Westerberg <mika.westerberg@linux.intel.com>2017-06-06 08:25:15 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-06-09 05:42:43 -0400
commitbdccf295d7cdf6f28ceec1dcc31a79d0a1697d21 (patch)
tree41926128da459fc10bfaba4b3ce6feec0cab1a0e /drivers/thunderbolt
parent3e13676862f90dbf5b00d57d5599e57788289897 (diff)
thunderbolt: Do not touch the hardware if the NHI is gone on resume
On PCs the NHI host controller is only present when there is a device connected. When the last device is disconnected the host controller will dissappear shortly (within 10s). Now if that happens when we are suspended we should not try to touch the hardware anymore, so add a flag for this and check it before we re-enable rings. Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Reviewed-by: Yehezkel Bernat <yehezkel.bernat@intel.com> Reviewed-by: Michael Jamet <michael.jamet@intel.com> Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Signed-off-by: Andreas Noever <andreas.noever@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/thunderbolt')
-rw-r--r--drivers/thunderbolt/nhi.c12
-rw-r--r--drivers/thunderbolt/nhi.h3
2 files changed, 15 insertions, 0 deletions
diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c
index c358c074f925..14311535661d 100644
--- a/drivers/thunderbolt/nhi.c
+++ b/drivers/thunderbolt/nhi.c
@@ -403,6 +403,8 @@ void ring_start(struct tb_ring *ring)
403{ 403{
404 mutex_lock(&ring->nhi->lock); 404 mutex_lock(&ring->nhi->lock);
405 mutex_lock(&ring->lock); 405 mutex_lock(&ring->lock);
406 if (ring->nhi->going_away)
407 goto err;
406 if (ring->running) { 408 if (ring->running) {
407 dev_WARN(&ring->nhi->pdev->dev, "ring already started\n"); 409 dev_WARN(&ring->nhi->pdev->dev, "ring already started\n");
408 goto err; 410 goto err;
@@ -449,6 +451,8 @@ void ring_stop(struct tb_ring *ring)
449 mutex_lock(&ring->lock); 451 mutex_lock(&ring->lock);
450 dev_info(&ring->nhi->pdev->dev, "stopping %s %d\n", 452 dev_info(&ring->nhi->pdev->dev, "stopping %s %d\n",
451 RING_TYPE(ring), ring->hop); 453 RING_TYPE(ring), ring->hop);
454 if (ring->nhi->going_away)
455 goto err;
452 if (!ring->running) { 456 if (!ring->running) {
453 dev_WARN(&ring->nhi->pdev->dev, "%s %d already stopped\n", 457 dev_WARN(&ring->nhi->pdev->dev, "%s %d already stopped\n",
454 RING_TYPE(ring), ring->hop); 458 RING_TYPE(ring), ring->hop);
@@ -653,6 +657,14 @@ static int nhi_resume_noirq(struct device *dev)
653 struct pci_dev *pdev = to_pci_dev(dev); 657 struct pci_dev *pdev = to_pci_dev(dev);
654 struct tb *tb = pci_get_drvdata(pdev); 658 struct tb *tb = pci_get_drvdata(pdev);
655 659
660 /*
661 * Check that the device is still there. It may be that the user
662 * unplugged last device which causes the host controller to go
663 * away on PCs.
664 */
665 if (!pci_device_is_present(pdev))
666 tb->nhi->going_away = true;
667
656 return tb_domain_resume_noirq(tb); 668 return tb_domain_resume_noirq(tb);
657} 669}
658 670
diff --git a/drivers/thunderbolt/nhi.h b/drivers/thunderbolt/nhi.h
index 446ff6dac91d..953864ae0ab3 100644
--- a/drivers/thunderbolt/nhi.h
+++ b/drivers/thunderbolt/nhi.h
@@ -20,6 +20,8 @@
20 * @tx_rings: All Tx rings available on this host controller 20 * @tx_rings: All Tx rings available on this host controller
21 * @rx_rings: All Rx rings available on this host controller 21 * @rx_rings: All Rx rings available on this host controller
22 * @msix_ida: Used to allocate MSI-X vectors for rings 22 * @msix_ida: Used to allocate MSI-X vectors for rings
23 * @going_away: The host controller device is about to disappear so when
24 * this flag is set, avoid touching the hardware anymore.
23 * @interrupt_work: Work scheduled to handle ring interrupt when no 25 * @interrupt_work: Work scheduled to handle ring interrupt when no
24 * MSI-X is used. 26 * MSI-X is used.
25 * @hop_count: Number of rings (end point hops) supported by NHI. 27 * @hop_count: Number of rings (end point hops) supported by NHI.
@@ -31,6 +33,7 @@ struct tb_nhi {
31 struct tb_ring **tx_rings; 33 struct tb_ring **tx_rings;
32 struct tb_ring **rx_rings; 34 struct tb_ring **rx_rings;
33 struct ida msix_ida; 35 struct ida msix_ida;
36 bool going_away;
34 struct work_struct interrupt_work; 37 struct work_struct interrupt_work;
35 u32 hop_count; 38 u32 hop_count;
36}; 39};