aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/thunderbolt/nhi.c
diff options
context:
space:
mode:
authorAndreas Noever <andreas.noever@gmail.com>2014-06-03 16:04:12 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-06-19 17:13:00 -0400
commit23dd5bb49d986f37977ed80dd2ca65040ead4392 (patch)
tree390db91ea55659f22ca93a15ac41bf584bd3a9b9 /drivers/thunderbolt/nhi.c
parentc90553b3c4ac2389a71a5c012b6e5bb1160d48a7 (diff)
thunderbolt: Add suspend/hibernate support
We use _noirq since we have to restore the pci tunnels before the pci core wakes the tunneled devices. Signed-off-by: Andreas Noever <andreas.noever@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/thunderbolt/nhi.c')
-rw-r--r--drivers/thunderbolt/nhi.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c
index d2b9ce857818..346b41e7d5d1 100644
--- a/drivers/thunderbolt/nhi.c
+++ b/drivers/thunderbolt/nhi.c
@@ -7,6 +7,7 @@
7 * Copyright (c) 2014 Andreas Noever <andreas.noever@gmail.com> 7 * Copyright (c) 2014 Andreas Noever <andreas.noever@gmail.com>
8 */ 8 */
9 9
10#include <linux/pm_runtime.h>
10#include <linux/slab.h> 11#include <linux/slab.h>
11#include <linux/errno.h> 12#include <linux/errno.h>
12#include <linux/pci.h> 13#include <linux/pci.h>
@@ -492,6 +493,22 @@ static irqreturn_t nhi_msi(int irq, void *data)
492 return IRQ_HANDLED; 493 return IRQ_HANDLED;
493} 494}
494 495
496static int nhi_suspend_noirq(struct device *dev)
497{
498 struct pci_dev *pdev = to_pci_dev(dev);
499 struct tb *tb = pci_get_drvdata(pdev);
500 thunderbolt_suspend(tb);
501 return 0;
502}
503
504static int nhi_resume_noirq(struct device *dev)
505{
506 struct pci_dev *pdev = to_pci_dev(dev);
507 struct tb *tb = pci_get_drvdata(pdev);
508 thunderbolt_resume(tb);
509 return 0;
510}
511
495static void nhi_shutdown(struct tb_nhi *nhi) 512static void nhi_shutdown(struct tb_nhi *nhi)
496{ 513{
497 int i; 514 int i;
@@ -600,6 +617,21 @@ static void nhi_remove(struct pci_dev *pdev)
600 nhi_shutdown(nhi); 617 nhi_shutdown(nhi);
601} 618}
602 619
620/*
621 * The tunneled pci bridges are siblings of us. Use resume_noirq to reenable
622 * the tunnels asap. A corresponding pci quirk blocks the downstream bridges
623 * resume_noirq until we are done.
624 */
625static const struct dev_pm_ops nhi_pm_ops = {
626 .suspend_noirq = nhi_suspend_noirq,
627 .resume_noirq = nhi_resume_noirq,
628 .freeze_noirq = nhi_suspend_noirq, /*
629 * we just disable hotplug, the
630 * pci-tunnels stay alive.
631 */
632 .restore_noirq = nhi_resume_noirq,
633};
634
603struct pci_device_id nhi_ids[] = { 635struct pci_device_id nhi_ids[] = {
604 /* 636 /*
605 * We have to specify class, the TB bridges use the same device and 637 * We have to specify class, the TB bridges use the same device and
@@ -626,6 +658,7 @@ static struct pci_driver nhi_driver = {
626 .id_table = nhi_ids, 658 .id_table = nhi_ids,
627 .probe = nhi_probe, 659 .probe = nhi_probe,
628 .remove = nhi_remove, 660 .remove = nhi_remove,
661 .driver.pm = &nhi_pm_ops,
629}; 662};
630 663
631static int __init nhi_init(void) 664static int __init nhi_init(void)