diff options
author | Andreas Noever <andreas.noever@gmail.com> | 2014-06-03 22:04:12 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-06-19 14:13:00 -0700 |
commit | 23dd5bb49d986f37977ed80dd2ca65040ead4392 (patch) | |
tree | 390db91ea55659f22ca93a15ac41bf584bd3a9b9 /drivers/thunderbolt/nhi.c | |
parent | c90553b3c4ac2389a71a5c012b6e5bb1160d48a7 (diff) | |
download | linux-23dd5bb49d986f37977ed80dd2ca65040ead4392.tar.gz linux-23dd5bb49d986f37977ed80dd2ca65040ead4392.tar.xz |
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.c | 33 |
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 @@ * Copyright (c) 2014 Andreas Noever <andreas.noever@gmail.com> */ +#include <linux/pm_runtime.h> #include <linux/slab.h> #include <linux/errno.h> #include <linux/pci.h> @@ -492,6 +493,22 @@ static irqreturn_t nhi_msi(int irq, void *data) return IRQ_HANDLED; } +static int nhi_suspend_noirq(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct tb *tb = pci_get_drvdata(pdev); + thunderbolt_suspend(tb); + return 0; +} + +static int nhi_resume_noirq(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + struct tb *tb = pci_get_drvdata(pdev); + thunderbolt_resume(tb); + return 0; +} + static void nhi_shutdown(struct tb_nhi *nhi) { int i; @@ -600,6 +617,21 @@ static void nhi_remove(struct pci_dev *pdev) nhi_shutdown(nhi); } +/* + * The tunneled pci bridges are siblings of us. Use resume_noirq to reenable + * the tunnels asap. A corresponding pci quirk blocks the downstream bridges + * resume_noirq until we are done. + */ +static const struct dev_pm_ops nhi_pm_ops = { + .suspend_noirq = nhi_suspend_noirq, + .resume_noirq = nhi_resume_noirq, + .freeze_noirq = nhi_suspend_noirq, /* + * we just disable hotplug, the + * pci-tunnels stay alive. + */ + .restore_noirq = nhi_resume_noirq, +}; + struct pci_device_id nhi_ids[] = { /* * We have to specify class, the TB bridges use the same device and @@ -626,6 +658,7 @@ static struct pci_driver nhi_driver = { .id_table = nhi_ids, .probe = nhi_probe, .remove = nhi_remove, + .driver.pm = &nhi_pm_ops, }; static int __init nhi_init(void) |