summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMika Westerberg <mika.westerberg@linux.intel.com>2018-07-25 04:48:39 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-07-25 04:55:29 -0400
commit2d8ff0b586fb1c5bd81a3ab286dcc6bbc432044e (patch)
tree0bdc18fec7a9d72e29b0b754a24b9a1df876b34b
parentfa3af1cb1ec073265c9c87ec44faf006f2f12d96 (diff)
thunderbolt: Add support for runtime PM
When Thunderbolt host controller is set to RTD3 mode (Runtime D3) it is present all the time. Because of this it is important to runtime suspend the controller whenever possible. In case of ICM we have following rules which all needs to be true before the host controller can be put to D3: - The controller firmware reports to support RTD3 - All the connected devices announce support for RTD3 - There is no active XDomain connection Implement this using standard Linux runtime PM APIs so that when all the children devices are runtime suspended, the Thunderbolt host controller PCI device is runtime suspended as well. The ICM firmware then starts powering down power domains towards RTD3 but it can prevent this if it detects that there is an active Display Port stream (this is not visible to the software, though). The Thunderbolt host controller will be runtime resumed either when there is a remote wake event (device is connected or disconnected), or when there is access from userspace that requires hardware access. Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/thunderbolt/domain.c42
-rw-r--r--drivers/thunderbolt/icm.c119
-rw-r--r--drivers/thunderbolt/nhi.c38
-rw-r--r--drivers/thunderbolt/switch.c65
-rw-r--r--drivers/thunderbolt/tb.h10
-rw-r--r--drivers/thunderbolt/tb_msgs.h4
-rw-r--r--drivers/thunderbolt/xdomain.c18
7 files changed, 276 insertions, 20 deletions
diff --git a/drivers/thunderbolt/domain.c b/drivers/thunderbolt/domain.c
index e377128663e9..092381e2accf 100644
--- a/drivers/thunderbolt/domain.c
+++ b/drivers/thunderbolt/domain.c
@@ -12,6 +12,7 @@
12#include <linux/device.h> 12#include <linux/device.h>
13#include <linux/idr.h> 13#include <linux/idr.h>
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/pm_runtime.h>
15#include <linux/slab.h> 16#include <linux/slab.h>
16#include <linux/random.h> 17#include <linux/random.h>
17#include <crypto/hash.h> 18#include <crypto/hash.h>
@@ -132,6 +133,8 @@ static ssize_t boot_acl_show(struct device *dev, struct device_attribute *attr,
132 if (!uuids) 133 if (!uuids)
133 return -ENOMEM; 134 return -ENOMEM;
134 135
136 pm_runtime_get_sync(&tb->dev);
137
135 if (mutex_lock_interruptible(&tb->lock)) { 138 if (mutex_lock_interruptible(&tb->lock)) {
136 ret = -ERESTARTSYS; 139 ret = -ERESTARTSYS;
137 goto out; 140 goto out;
@@ -153,7 +156,10 @@ static ssize_t boot_acl_show(struct device *dev, struct device_attribute *attr,
153 } 156 }
154 157
155out: 158out:
159 pm_runtime_mark_last_busy(&tb->dev);
160 pm_runtime_put_autosuspend(&tb->dev);
156 kfree(uuids); 161 kfree(uuids);
162
157 return ret; 163 return ret;
158} 164}
159 165
@@ -208,9 +214,11 @@ static ssize_t boot_acl_store(struct device *dev, struct device_attribute *attr,
208 goto err_free_acl; 214 goto err_free_acl;
209 } 215 }
210 216
217 pm_runtime_get_sync(&tb->dev);
218
211 if (mutex_lock_interruptible(&tb->lock)) { 219 if (mutex_lock_interruptible(&tb->lock)) {
212 ret = -ERESTARTSYS; 220 ret = -ERESTARTSYS;
213 goto err_free_acl; 221 goto err_rpm_put;
214 } 222 }
215 ret = tb->cm_ops->set_boot_acl(tb, acl, tb->nboot_acl); 223 ret = tb->cm_ops->set_boot_acl(tb, acl, tb->nboot_acl);
216 if (!ret) { 224 if (!ret) {
@@ -219,6 +227,9 @@ static ssize_t boot_acl_store(struct device *dev, struct device_attribute *attr,
219 } 227 }
220 mutex_unlock(&tb->lock); 228 mutex_unlock(&tb->lock);
221 229
230err_rpm_put:
231 pm_runtime_mark_last_busy(&tb->dev);
232 pm_runtime_put_autosuspend(&tb->dev);
222err_free_acl: 233err_free_acl:
223 kfree(acl); 234 kfree(acl);
224err_free_str: 235err_free_str:
@@ -430,6 +441,13 @@ int tb_domain_add(struct tb *tb)
430 /* This starts event processing */ 441 /* This starts event processing */
431 mutex_unlock(&tb->lock); 442 mutex_unlock(&tb->lock);
432 443
444 pm_runtime_no_callbacks(&tb->dev);
445 pm_runtime_set_active(&tb->dev);
446 pm_runtime_enable(&tb->dev);
447 pm_runtime_set_autosuspend_delay(&tb->dev, TB_AUTOSUSPEND_DELAY);
448 pm_runtime_mark_last_busy(&tb->dev);
449 pm_runtime_use_autosuspend(&tb->dev);
450
433 return 0; 451 return 0;
434 452
435err_domain_del: 453err_domain_del:
@@ -518,6 +536,28 @@ void tb_domain_complete(struct tb *tb)
518 tb->cm_ops->complete(tb); 536 tb->cm_ops->complete(tb);
519} 537}
520 538
539int tb_domain_runtime_suspend(struct tb *tb)
540{
541 if (tb->cm_ops->runtime_suspend) {
542 int ret = tb->cm_ops->runtime_suspend(tb);
543 if (ret)
544 return ret;
545 }
546 tb_ctl_stop(tb->ctl);
547 return 0;
548}
549
550int tb_domain_runtime_resume(struct tb *tb)
551{
552 tb_ctl_start(tb->ctl);
553 if (tb->cm_ops->runtime_resume) {
554 int ret = tb->cm_ops->runtime_resume(tb);
555 if (ret)
556 return ret;
557 }
558 return 0;
559}
560
521/** 561/**
522 * tb_domain_approve_switch() - Approve switch 562 * tb_domain_approve_switch() - Approve switch
523 * @tb: Domain the switch belongs to 563 * @tb: Domain the switch belongs to
diff --git a/drivers/thunderbolt/icm.c b/drivers/thunderbolt/icm.c
index e0930dbbcf47..e1e264a9a4c7 100644
--- a/drivers/thunderbolt/icm.c
+++ b/drivers/thunderbolt/icm.c
@@ -15,6 +15,7 @@
15#include <linux/delay.h> 15#include <linux/delay.h>
16#include <linux/mutex.h> 16#include <linux/mutex.h>
17#include <linux/pci.h> 17#include <linux/pci.h>
18#include <linux/pm_runtime.h>
18#include <linux/platform_data/x86/apple.h> 19#include <linux/platform_data/x86/apple.h>
19#include <linux/sizes.h> 20#include <linux/sizes.h>
20#include <linux/slab.h> 21#include <linux/slab.h>
@@ -57,6 +58,7 @@
57 * (only set when @upstream_port is not %NULL) 58 * (only set when @upstream_port is not %NULL)
58 * @safe_mode: ICM is in safe mode 59 * @safe_mode: ICM is in safe mode
59 * @max_boot_acl: Maximum number of preboot ACL entries (%0 if not supported) 60 * @max_boot_acl: Maximum number of preboot ACL entries (%0 if not supported)
61 * @rpm: Does the controller support runtime PM (RTD3)
60 * @is_supported: Checks if we can support ICM on this controller 62 * @is_supported: Checks if we can support ICM on this controller
61 * @get_mode: Read and return the ICM firmware mode (optional) 63 * @get_mode: Read and return the ICM firmware mode (optional)
62 * @get_route: Find a route string for given switch 64 * @get_route: Find a route string for given switch
@@ -74,13 +76,14 @@ struct icm {
74 size_t max_boot_acl; 76 size_t max_boot_acl;
75 int vnd_cap; 77 int vnd_cap;
76 bool safe_mode; 78 bool safe_mode;
79 bool rpm;
77 bool (*is_supported)(struct tb *tb); 80 bool (*is_supported)(struct tb *tb);
78 int (*get_mode)(struct tb *tb); 81 int (*get_mode)(struct tb *tb);
79 int (*get_route)(struct tb *tb, u8 link, u8 depth, u64 *route); 82 int (*get_route)(struct tb *tb, u8 link, u8 depth, u64 *route);
80 void (*save_devices)(struct tb *tb); 83 void (*save_devices)(struct tb *tb);
81 int (*driver_ready)(struct tb *tb, 84 int (*driver_ready)(struct tb *tb,
82 enum tb_security_level *security_level, 85 enum tb_security_level *security_level,
83 size_t *nboot_acl); 86 size_t *nboot_acl, bool *rpm);
84 void (*device_connected)(struct tb *tb, 87 void (*device_connected)(struct tb *tb,
85 const struct icm_pkg_header *hdr); 88 const struct icm_pkg_header *hdr);
86 void (*device_disconnected)(struct tb *tb, 89 void (*device_disconnected)(struct tb *tb,
@@ -97,6 +100,47 @@ struct icm_notification {
97 struct tb *tb; 100 struct tb *tb;
98}; 101};
99 102
103struct ep_name_entry {
104 u8 len;
105 u8 type;
106 u8 data[0];
107};
108
109#define EP_NAME_INTEL_VSS 0x10
110
111/* Intel Vendor specific structure */
112struct intel_vss {
113 u16 vendor;
114 u16 model;
115 u8 mc;
116 u8 flags;
117 u16 pci_devid;
118 u32 nvm_version;
119};
120
121#define INTEL_VSS_FLAGS_RTD3 BIT(0)
122
123static const struct intel_vss *parse_intel_vss(const void *ep_name, size_t size)
124{
125 const void *end = ep_name + size;
126
127 while (ep_name < end) {
128 const struct ep_name_entry *ep = ep_name;
129
130 if (!ep->len)
131 break;
132 if (ep_name + ep->len > end)
133 break;
134
135 if (ep->type == EP_NAME_INTEL_VSS)
136 return (const struct intel_vss *)ep->data;
137
138 ep_name += ep->len;
139 }
140
141 return NULL;
142}
143
100static inline struct tb *icm_to_tb(struct icm *icm) 144static inline struct tb *icm_to_tb(struct icm *icm)
101{ 145{
102 return ((void *)icm - sizeof(struct tb)); 146 return ((void *)icm - sizeof(struct tb));
@@ -267,7 +311,7 @@ static void icm_fr_save_devices(struct tb *tb)
267 311
268static int 312static int
269icm_fr_driver_ready(struct tb *tb, enum tb_security_level *security_level, 313icm_fr_driver_ready(struct tb *tb, enum tb_security_level *security_level,
270 size_t *nboot_acl) 314 size_t *nboot_acl, bool *rpm)
271{ 315{
272 struct icm_fr_pkg_driver_ready_response reply; 316 struct icm_fr_pkg_driver_ready_response reply;
273 struct icm_pkg_driver_ready request = { 317 struct icm_pkg_driver_ready request = {
@@ -417,15 +461,19 @@ static int icm_fr_disconnect_xdomain_paths(struct tb *tb, struct tb_xdomain *xd)
417} 461}
418 462
419static void add_switch(struct tb_switch *parent_sw, u64 route, 463static void add_switch(struct tb_switch *parent_sw, u64 route,
420 const uuid_t *uuid, u8 connection_id, u8 connection_key, 464 const uuid_t *uuid, const u8 *ep_name,
465 size_t ep_name_size, u8 connection_id, u8 connection_key,
421 u8 link, u8 depth, enum tb_security_level security_level, 466 u8 link, u8 depth, enum tb_security_level security_level,
422 bool authorized, bool boot) 467 bool authorized, bool boot)
423{ 468{
469 const struct intel_vss *vss;
424 struct tb_switch *sw; 470 struct tb_switch *sw;
425 471
472 pm_runtime_get_sync(&parent_sw->dev);
473
426 sw = tb_switch_alloc(parent_sw->tb, &parent_sw->dev, route); 474 sw = tb_switch_alloc(parent_sw->tb, &parent_sw->dev, route);
427 if (!sw) 475 if (!sw)
428 return; 476 goto out;
429 477
430 sw->uuid = kmemdup(uuid, sizeof(*uuid), GFP_KERNEL); 478 sw->uuid = kmemdup(uuid, sizeof(*uuid), GFP_KERNEL);
431 sw->connection_id = connection_id; 479 sw->connection_id = connection_id;
@@ -436,6 +484,10 @@ static void add_switch(struct tb_switch *parent_sw, u64 route,
436 sw->security_level = security_level; 484 sw->security_level = security_level;
437 sw->boot = boot; 485 sw->boot = boot;
438 486
487 vss = parse_intel_vss(ep_name, ep_name_size);
488 if (vss)
489 sw->rpm = !!(vss->flags & INTEL_VSS_FLAGS_RTD3);
490
439 /* Link the two switches now */ 491 /* Link the two switches now */
440 tb_port_at(route, parent_sw)->remote = tb_upstream_port(sw); 492 tb_port_at(route, parent_sw)->remote = tb_upstream_port(sw);
441 tb_upstream_port(sw)->remote = tb_port_at(route, parent_sw); 493 tb_upstream_port(sw)->remote = tb_port_at(route, parent_sw);
@@ -443,8 +495,11 @@ static void add_switch(struct tb_switch *parent_sw, u64 route,
443 if (tb_switch_add(sw)) { 495 if (tb_switch_add(sw)) {
444 tb_port_at(tb_route(sw), parent_sw)->remote = NULL; 496 tb_port_at(tb_route(sw), parent_sw)->remote = NULL;
445 tb_switch_put(sw); 497 tb_switch_put(sw);
446 return;
447 } 498 }
499
500out:
501 pm_runtime_mark_last_busy(&parent_sw->dev);
502 pm_runtime_put_autosuspend(&parent_sw->dev);
448} 503}
449 504
450static void update_switch(struct tb_switch *parent_sw, struct tb_switch *sw, 505static void update_switch(struct tb_switch *parent_sw, struct tb_switch *sw,
@@ -484,9 +539,11 @@ static void add_xdomain(struct tb_switch *sw, u64 route,
484{ 539{
485 struct tb_xdomain *xd; 540 struct tb_xdomain *xd;
486 541
542 pm_runtime_get_sync(&sw->dev);
543
487 xd = tb_xdomain_alloc(sw->tb, &sw->dev, route, local_uuid, remote_uuid); 544 xd = tb_xdomain_alloc(sw->tb, &sw->dev, route, local_uuid, remote_uuid);
488 if (!xd) 545 if (!xd)
489 return; 546 goto out;
490 547
491 xd->link = link; 548 xd->link = link;
492 xd->depth = depth; 549 xd->depth = depth;
@@ -494,6 +551,10 @@ static void add_xdomain(struct tb_switch *sw, u64 route,
494 tb_port_at(route, sw)->xdomain = xd; 551 tb_port_at(route, sw)->xdomain = xd;
495 552
496 tb_xdomain_add(xd); 553 tb_xdomain_add(xd);
554
555out:
556 pm_runtime_mark_last_busy(&sw->dev);
557 pm_runtime_put_autosuspend(&sw->dev);
497} 558}
498 559
499static void update_xdomain(struct tb_xdomain *xd, u64 route, u8 link) 560static void update_xdomain(struct tb_xdomain *xd, u64 route, u8 link)
@@ -631,7 +692,8 @@ icm_fr_device_connected(struct tb *tb, const struct icm_pkg_header *hdr)
631 return; 692 return;
632 } 693 }
633 694
634 add_switch(parent_sw, route, &pkg->ep_uuid, pkg->connection_id, 695 add_switch(parent_sw, route, &pkg->ep_uuid, (const u8 *)pkg->ep_name,
696 sizeof(pkg->ep_name), pkg->connection_id,
635 pkg->connection_key, link, depth, security_level, 697 pkg->connection_key, link, depth, security_level,
636 authorized, boot); 698 authorized, boot);
637 699
@@ -779,7 +841,7 @@ icm_fr_xdomain_disconnected(struct tb *tb, const struct icm_pkg_header *hdr)
779 841
780static int 842static int
781icm_tr_driver_ready(struct tb *tb, enum tb_security_level *security_level, 843icm_tr_driver_ready(struct tb *tb, enum tb_security_level *security_level,
782 size_t *nboot_acl) 844 size_t *nboot_acl, bool *rpm)
783{ 845{
784 struct icm_tr_pkg_driver_ready_response reply; 846 struct icm_tr_pkg_driver_ready_response reply;
785 struct icm_pkg_driver_ready request = { 847 struct icm_pkg_driver_ready request = {
@@ -798,6 +860,9 @@ icm_tr_driver_ready(struct tb *tb, enum tb_security_level *security_level,
798 if (nboot_acl) 860 if (nboot_acl)
799 *nboot_acl = (reply.info & ICM_TR_INFO_BOOT_ACL_MASK) >> 861 *nboot_acl = (reply.info & ICM_TR_INFO_BOOT_ACL_MASK) >>
800 ICM_TR_INFO_BOOT_ACL_SHIFT; 862 ICM_TR_INFO_BOOT_ACL_SHIFT;
863 if (rpm)
864 *rpm = !!(reply.hdr.flags & ICM_TR_FLAGS_RTD3);
865
801 return 0; 866 return 0;
802} 867}
803 868
@@ -1027,7 +1092,8 @@ icm_tr_device_connected(struct tb *tb, const struct icm_pkg_header *hdr)
1027 return; 1092 return;
1028 } 1093 }
1029 1094
1030 add_switch(parent_sw, route, &pkg->ep_uuid, pkg->connection_id, 1095 add_switch(parent_sw, route, &pkg->ep_uuid, (const u8 *)pkg->ep_name,
1096 sizeof(pkg->ep_name), pkg->connection_id,
1031 0, 0, 0, security_level, authorized, boot); 1097 0, 0, 0, security_level, authorized, boot);
1032 1098
1033 tb_switch_put(parent_sw); 1099 tb_switch_put(parent_sw);
@@ -1206,7 +1272,7 @@ static int icm_ar_get_mode(struct tb *tb)
1206 1272
1207static int 1273static int
1208icm_ar_driver_ready(struct tb *tb, enum tb_security_level *security_level, 1274icm_ar_driver_ready(struct tb *tb, enum tb_security_level *security_level,
1209 size_t *nboot_acl) 1275 size_t *nboot_acl, bool *rpm)
1210{ 1276{
1211 struct icm_ar_pkg_driver_ready_response reply; 1277 struct icm_ar_pkg_driver_ready_response reply;
1212 struct icm_pkg_driver_ready request = { 1278 struct icm_pkg_driver_ready request = {
@@ -1225,6 +1291,9 @@ icm_ar_driver_ready(struct tb *tb, enum tb_security_level *security_level,
1225 if (nboot_acl && (reply.info & ICM_AR_INFO_BOOT_ACL_SUPPORTED)) 1291 if (nboot_acl && (reply.info & ICM_AR_INFO_BOOT_ACL_SUPPORTED))
1226 *nboot_acl = (reply.info & ICM_AR_INFO_BOOT_ACL_MASK) >> 1292 *nboot_acl = (reply.info & ICM_AR_INFO_BOOT_ACL_MASK) >>
1227 ICM_AR_INFO_BOOT_ACL_SHIFT; 1293 ICM_AR_INFO_BOOT_ACL_SHIFT;
1294 if (rpm)
1295 *rpm = !!(reply.hdr.flags & ICM_AR_FLAGS_RTD3);
1296
1228 return 0; 1297 return 0;
1229} 1298}
1230 1299
@@ -1378,13 +1447,13 @@ static void icm_handle_event(struct tb *tb, enum tb_cfg_pkg_type type,
1378 1447
1379static int 1448static int
1380__icm_driver_ready(struct tb *tb, enum tb_security_level *security_level, 1449__icm_driver_ready(struct tb *tb, enum tb_security_level *security_level,
1381 size_t *nboot_acl) 1450 size_t *nboot_acl, bool *rpm)
1382{ 1451{
1383 struct icm *icm = tb_priv(tb); 1452 struct icm *icm = tb_priv(tb);
1384 unsigned int retries = 50; 1453 unsigned int retries = 50;
1385 int ret; 1454 int ret;
1386 1455
1387 ret = icm->driver_ready(tb, security_level, nboot_acl); 1456 ret = icm->driver_ready(tb, security_level, nboot_acl, rpm);
1388 if (ret) { 1457 if (ret) {
1389 tb_err(tb, "failed to send driver ready to ICM\n"); 1458 tb_err(tb, "failed to send driver ready to ICM\n");
1390 return ret; 1459 return ret;
@@ -1654,7 +1723,8 @@ static int icm_driver_ready(struct tb *tb)
1654 return 0; 1723 return 0;
1655 } 1724 }
1656 1725
1657 ret = __icm_driver_ready(tb, &tb->security_level, &tb->nboot_acl); 1726 ret = __icm_driver_ready(tb, &tb->security_level, &tb->nboot_acl,
1727 &icm->rpm);
1658 if (ret) 1728 if (ret)
1659 return ret; 1729 return ret;
1660 1730
@@ -1760,7 +1830,7 @@ static void icm_complete(struct tb *tb)
1760 * Now all existing children should be resumed, start events 1830 * Now all existing children should be resumed, start events
1761 * from ICM to get updated status. 1831 * from ICM to get updated status.
1762 */ 1832 */
1763 __icm_driver_ready(tb, NULL, NULL); 1833 __icm_driver_ready(tb, NULL, NULL, NULL);
1764 1834
1765 /* 1835 /*
1766 * We do not get notifications of devices that have been 1836 * We do not get notifications of devices that have been
@@ -1770,6 +1840,22 @@ static void icm_complete(struct tb *tb)
1770 queue_delayed_work(tb->wq, &icm->rescan_work, msecs_to_jiffies(500)); 1840 queue_delayed_work(tb->wq, &icm->rescan_work, msecs_to_jiffies(500));
1771} 1841}
1772 1842
1843static int icm_runtime_suspend(struct tb *tb)
1844{
1845 nhi_mailbox_cmd(tb->nhi, NHI_MAILBOX_DRV_UNLOADS, 0);
1846 return 0;
1847}
1848
1849static int icm_runtime_resume(struct tb *tb)
1850{
1851 /*
1852 * We can reuse the same resume functionality than with system
1853 * suspend.
1854 */
1855 icm_complete(tb);
1856 return 0;
1857}
1858
1773static int icm_start(struct tb *tb) 1859static int icm_start(struct tb *tb)
1774{ 1860{
1775 struct icm *icm = tb_priv(tb); 1861 struct icm *icm = tb_priv(tb);
@@ -1788,6 +1874,7 @@ static int icm_start(struct tb *tb)
1788 * prevent root switch NVM upgrade on Macs for now. 1874 * prevent root switch NVM upgrade on Macs for now.
1789 */ 1875 */
1790 tb->root_switch->no_nvm_upgrade = x86_apple_machine; 1876 tb->root_switch->no_nvm_upgrade = x86_apple_machine;
1877 tb->root_switch->rpm = icm->rpm;
1791 1878
1792 ret = tb_switch_add(tb->root_switch); 1879 ret = tb_switch_add(tb->root_switch);
1793 if (ret) { 1880 if (ret) {
@@ -1836,6 +1923,8 @@ static const struct tb_cm_ops icm_ar_ops = {
1836 .stop = icm_stop, 1923 .stop = icm_stop,
1837 .suspend = icm_suspend, 1924 .suspend = icm_suspend,
1838 .complete = icm_complete, 1925 .complete = icm_complete,
1926 .runtime_suspend = icm_runtime_suspend,
1927 .runtime_resume = icm_runtime_resume,
1839 .handle_event = icm_handle_event, 1928 .handle_event = icm_handle_event,
1840 .get_boot_acl = icm_ar_get_boot_acl, 1929 .get_boot_acl = icm_ar_get_boot_acl,
1841 .set_boot_acl = icm_ar_set_boot_acl, 1930 .set_boot_acl = icm_ar_set_boot_acl,
@@ -1854,6 +1943,8 @@ static const struct tb_cm_ops icm_tr_ops = {
1854 .stop = icm_stop, 1943 .stop = icm_stop,
1855 .suspend = icm_suspend, 1944 .suspend = icm_suspend,
1856 .complete = icm_complete, 1945 .complete = icm_complete,
1946 .runtime_suspend = icm_runtime_suspend,
1947 .runtime_resume = icm_runtime_resume,
1857 .handle_event = icm_handle_event, 1948 .handle_event = icm_handle_event,
1858 .get_boot_acl = icm_ar_get_boot_acl, 1949 .get_boot_acl = icm_ar_get_boot_acl,
1859 .set_boot_acl = icm_ar_set_boot_acl, 1950 .set_boot_acl = icm_ar_set_boot_acl,
diff --git a/drivers/thunderbolt/nhi.c b/drivers/thunderbolt/nhi.c
index e3b7695fe37e..88cff05a1808 100644
--- a/drivers/thunderbolt/nhi.c
+++ b/drivers/thunderbolt/nhi.c
@@ -900,7 +900,32 @@ static void nhi_complete(struct device *dev)
900 struct pci_dev *pdev = to_pci_dev(dev); 900 struct pci_dev *pdev = to_pci_dev(dev);
901 struct tb *tb = pci_get_drvdata(pdev); 901 struct tb *tb = pci_get_drvdata(pdev);
902 902
903 tb_domain_complete(tb); 903 /*
904 * If we were runtime suspended when system suspend started,
905 * schedule runtime resume now. It should bring the domain back
906 * to functional state.
907 */
908 if (pm_runtime_suspended(&pdev->dev))
909 pm_runtime_resume(&pdev->dev);
910 else
911 tb_domain_complete(tb);
912}
913
914static int nhi_runtime_suspend(struct device *dev)
915{
916 struct pci_dev *pdev = to_pci_dev(dev);
917 struct tb *tb = pci_get_drvdata(pdev);
918
919 return tb_domain_runtime_suspend(tb);
920}
921
922static int nhi_runtime_resume(struct device *dev)
923{
924 struct pci_dev *pdev = to_pci_dev(dev);
925 struct tb *tb = pci_get_drvdata(pdev);
926
927 nhi_enable_int_throttling(tb->nhi);
928 return tb_domain_runtime_resume(tb);
904} 929}
905 930
906static void nhi_shutdown(struct tb_nhi *nhi) 931static void nhi_shutdown(struct tb_nhi *nhi)
@@ -1048,6 +1073,11 @@ static int nhi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1048 } 1073 }
1049 pci_set_drvdata(pdev, tb); 1074 pci_set_drvdata(pdev, tb);
1050 1075
1076 pm_runtime_allow(&pdev->dev);
1077 pm_runtime_set_autosuspend_delay(&pdev->dev, TB_AUTOSUSPEND_DELAY);
1078 pm_runtime_use_autosuspend(&pdev->dev);
1079 pm_runtime_put_autosuspend(&pdev->dev);
1080
1051 return 0; 1081 return 0;
1052} 1082}
1053 1083
@@ -1056,6 +1086,10 @@ static void nhi_remove(struct pci_dev *pdev)
1056 struct tb *tb = pci_get_drvdata(pdev); 1086 struct tb *tb = pci_get_drvdata(pdev);
1057 struct tb_nhi *nhi = tb->nhi; 1087 struct tb_nhi *nhi = tb->nhi;
1058 1088
1089 pm_runtime_get_sync(&pdev->dev);
1090 pm_runtime_dont_use_autosuspend(&pdev->dev);
1091 pm_runtime_forbid(&pdev->dev);
1092
1059 tb_domain_remove(tb); 1093 tb_domain_remove(tb);
1060 nhi_shutdown(nhi); 1094 nhi_shutdown(nhi);
1061} 1095}
@@ -1078,6 +1112,8 @@ static const struct dev_pm_ops nhi_pm_ops = {
1078 .freeze = nhi_suspend, 1112 .freeze = nhi_suspend,
1079 .poweroff = nhi_suspend, 1113 .poweroff = nhi_suspend,
1080 .complete = nhi_complete, 1114 .complete = nhi_complete,
1115 .runtime_suspend = nhi_runtime_suspend,
1116 .runtime_resume = nhi_runtime_resume,
1081}; 1117};
1082 1118
1083static struct pci_device_id nhi_ids[] = { 1119static struct pci_device_id nhi_ids[] = {
diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c
index 25758671ddf4..7442bc4c6433 100644
--- a/drivers/thunderbolt/switch.c
+++ b/drivers/thunderbolt/switch.c
@@ -8,6 +8,7 @@
8#include <linux/delay.h> 8#include <linux/delay.h>
9#include <linux/idr.h> 9#include <linux/idr.h>
10#include <linux/nvmem-provider.h> 10#include <linux/nvmem-provider.h>
11#include <linux/pm_runtime.h>
11#include <linux/sizes.h> 12#include <linux/sizes.h>
12#include <linux/slab.h> 13#include <linux/slab.h>
13#include <linux/vmalloc.h> 14#include <linux/vmalloc.h>
@@ -236,8 +237,14 @@ static int tb_switch_nvm_read(void *priv, unsigned int offset, void *val,
236 size_t bytes) 237 size_t bytes)
237{ 238{
238 struct tb_switch *sw = priv; 239 struct tb_switch *sw = priv;
240 int ret;
241
242 pm_runtime_get_sync(&sw->dev);
243 ret = dma_port_flash_read(sw->dma_port, offset, val, bytes);
244 pm_runtime_mark_last_busy(&sw->dev);
245 pm_runtime_put_autosuspend(&sw->dev);
239 246
240 return dma_port_flash_read(sw->dma_port, offset, val, bytes); 247 return ret;
241} 248}
242 249
243static int tb_switch_nvm_write(void *priv, unsigned int offset, void *val, 250static int tb_switch_nvm_write(void *priv, unsigned int offset, void *val,
@@ -722,6 +729,7 @@ static int tb_switch_set_authorized(struct tb_switch *sw, unsigned int val)
722 * the new tunnel too early. 729 * the new tunnel too early.
723 */ 730 */
724 pci_lock_rescan_remove(); 731 pci_lock_rescan_remove();
732 pm_runtime_get_sync(&sw->dev);
725 733
726 switch (val) { 734 switch (val) {
727 /* Approve switch */ 735 /* Approve switch */
@@ -742,6 +750,8 @@ static int tb_switch_set_authorized(struct tb_switch *sw, unsigned int val)
742 break; 750 break;
743 } 751 }
744 752
753 pm_runtime_mark_last_busy(&sw->dev);
754 pm_runtime_put_autosuspend(&sw->dev);
745 pci_unlock_rescan_remove(); 755 pci_unlock_rescan_remove();
746 756
747 if (!ret) { 757 if (!ret) {
@@ -888,9 +898,18 @@ static ssize_t nvm_authenticate_store(struct device *dev,
888 nvm_clear_auth_status(sw); 898 nvm_clear_auth_status(sw);
889 899
890 if (val) { 900 if (val) {
901 if (!sw->nvm->buf) {
902 ret = -EINVAL;
903 goto exit_unlock;
904 }
905
906 pm_runtime_get_sync(&sw->dev);
891 ret = nvm_validate_and_write(sw); 907 ret = nvm_validate_and_write(sw);
892 if (ret) 908 if (ret) {
909 pm_runtime_mark_last_busy(&sw->dev);
910 pm_runtime_put_autosuspend(&sw->dev);
893 goto exit_unlock; 911 goto exit_unlock;
912 }
894 913
895 sw->nvm->authenticating = true; 914 sw->nvm->authenticating = true;
896 915
@@ -898,6 +917,8 @@ static ssize_t nvm_authenticate_store(struct device *dev,
898 ret = nvm_authenticate_host(sw); 917 ret = nvm_authenticate_host(sw);
899 else 918 else
900 ret = nvm_authenticate_device(sw); 919 ret = nvm_authenticate_device(sw);
920 pm_runtime_mark_last_busy(&sw->dev);
921 pm_runtime_put_autosuspend(&sw->dev);
901 } 922 }
902 923
903exit_unlock: 924exit_unlock:
@@ -1023,9 +1044,29 @@ static void tb_switch_release(struct device *dev)
1023 kfree(sw); 1044 kfree(sw);
1024} 1045}
1025 1046
1047/*
1048 * Currently only need to provide the callbacks. Everything else is handled
1049 * in the connection manager.
1050 */
1051static int __maybe_unused tb_switch_runtime_suspend(struct device *dev)
1052{
1053 return 0;
1054}
1055
1056static int __maybe_unused tb_switch_runtime_resume(struct device *dev)
1057{
1058 return 0;
1059}
1060
1061static const struct dev_pm_ops tb_switch_pm_ops = {
1062 SET_RUNTIME_PM_OPS(tb_switch_runtime_suspend, tb_switch_runtime_resume,
1063 NULL)
1064};
1065
1026struct device_type tb_switch_type = { 1066struct device_type tb_switch_type = {
1027 .name = "thunderbolt_device", 1067 .name = "thunderbolt_device",
1028 .release = tb_switch_release, 1068 .release = tb_switch_release,
1069 .pm = &tb_switch_pm_ops,
1029}; 1070};
1030 1071
1031static int tb_switch_get_generation(struct tb_switch *sw) 1072static int tb_switch_get_generation(struct tb_switch *sw)
@@ -1365,10 +1406,21 @@ int tb_switch_add(struct tb_switch *sw)
1365 return ret; 1406 return ret;
1366 1407
1367 ret = tb_switch_nvm_add(sw); 1408 ret = tb_switch_nvm_add(sw);
1368 if (ret) 1409 if (ret) {
1369 device_del(&sw->dev); 1410 device_del(&sw->dev);
1411 return ret;
1412 }
1370 1413
1371 return ret; 1414 pm_runtime_set_active(&sw->dev);
1415 if (sw->rpm) {
1416 pm_runtime_set_autosuspend_delay(&sw->dev, TB_AUTOSUSPEND_DELAY);
1417 pm_runtime_use_autosuspend(&sw->dev);
1418 pm_runtime_mark_last_busy(&sw->dev);
1419 pm_runtime_enable(&sw->dev);
1420 pm_request_autosuspend(&sw->dev);
1421 }
1422
1423 return 0;
1372} 1424}
1373 1425
1374/** 1426/**
@@ -1383,6 +1435,11 @@ void tb_switch_remove(struct tb_switch *sw)
1383{ 1435{
1384 int i; 1436 int i;
1385 1437
1438 if (sw->rpm) {
1439 pm_runtime_get_sync(&sw->dev);
1440 pm_runtime_disable(&sw->dev);
1441 }
1442
1386 /* port 0 is the switch itself and never has a remote */ 1443 /* port 0 is the switch itself and never has a remote */
1387 for (i = 1; i <= sw->config.max_port_number; i++) { 1444 for (i = 1; i <= sw->config.max_port_number; i++) {
1388 if (tb_is_upstream_port(&sw->ports[i])) 1445 if (tb_is_upstream_port(&sw->ports[i]))
diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h
index 9d9f0ca16bfb..5067d69d0501 100644
--- a/drivers/thunderbolt/tb.h
+++ b/drivers/thunderbolt/tb.h
@@ -67,6 +67,7 @@ struct tb_switch_nvm {
67 * @no_nvm_upgrade: Prevent NVM upgrade of this switch 67 * @no_nvm_upgrade: Prevent NVM upgrade of this switch
68 * @safe_mode: The switch is in safe-mode 68 * @safe_mode: The switch is in safe-mode
69 * @boot: Whether the switch was already authorized on boot or not 69 * @boot: Whether the switch was already authorized on boot or not
70 * @rpm: The switch supports runtime PM
70 * @authorized: Whether the switch is authorized by user or policy 71 * @authorized: Whether the switch is authorized by user or policy
71 * @work: Work used to automatically authorize a switch 72 * @work: Work used to automatically authorize a switch
72 * @security_level: Switch supported security level 73 * @security_level: Switch supported security level
@@ -101,6 +102,7 @@ struct tb_switch {
101 bool no_nvm_upgrade; 102 bool no_nvm_upgrade;
102 bool safe_mode; 103 bool safe_mode;
103 bool boot; 104 bool boot;
105 bool rpm;
104 unsigned int authorized; 106 unsigned int authorized;
105 struct work_struct work; 107 struct work_struct work;
106 enum tb_security_level security_level; 108 enum tb_security_level security_level;
@@ -199,6 +201,8 @@ struct tb_path {
199 * @resume_noirq: Connection manager specific resume_noirq 201 * @resume_noirq: Connection manager specific resume_noirq
200 * @suspend: Connection manager specific suspend 202 * @suspend: Connection manager specific suspend
201 * @complete: Connection manager specific complete 203 * @complete: Connection manager specific complete
204 * @runtime_suspend: Connection manager specific runtime_suspend
205 * @runtime_resume: Connection manager specific runtime_resume
202 * @handle_event: Handle thunderbolt event 206 * @handle_event: Handle thunderbolt event
203 * @get_boot_acl: Get boot ACL list 207 * @get_boot_acl: Get boot ACL list
204 * @set_boot_acl: Set boot ACL list 208 * @set_boot_acl: Set boot ACL list
@@ -217,6 +221,8 @@ struct tb_cm_ops {
217 int (*resume_noirq)(struct tb *tb); 221 int (*resume_noirq)(struct tb *tb);
218 int (*suspend)(struct tb *tb); 222 int (*suspend)(struct tb *tb);
219 void (*complete)(struct tb *tb); 223 void (*complete)(struct tb *tb);
224 int (*runtime_suspend)(struct tb *tb);
225 int (*runtime_resume)(struct tb *tb);
220 void (*handle_event)(struct tb *tb, enum tb_cfg_pkg_type, 226 void (*handle_event)(struct tb *tb, enum tb_cfg_pkg_type,
221 const void *buf, size_t size); 227 const void *buf, size_t size);
222 int (*get_boot_acl)(struct tb *tb, uuid_t *uuids, size_t nuuids); 228 int (*get_boot_acl)(struct tb *tb, uuid_t *uuids, size_t nuuids);
@@ -235,6 +241,8 @@ static inline void *tb_priv(struct tb *tb)
235 return (void *)tb->privdata; 241 return (void *)tb->privdata;
236} 242}
237 243
244#define TB_AUTOSUSPEND_DELAY 15000 /* ms */
245
238/* helper functions & macros */ 246/* helper functions & macros */
239 247
240/** 248/**
@@ -364,6 +372,8 @@ int tb_domain_suspend_noirq(struct tb *tb);
364int tb_domain_resume_noirq(struct tb *tb); 372int tb_domain_resume_noirq(struct tb *tb);
365int tb_domain_suspend(struct tb *tb); 373int tb_domain_suspend(struct tb *tb);
366void tb_domain_complete(struct tb *tb); 374void tb_domain_complete(struct tb *tb);
375int tb_domain_runtime_suspend(struct tb *tb);
376int tb_domain_runtime_resume(struct tb *tb);
367int tb_domain_approve_switch(struct tb *tb, struct tb_switch *sw); 377int tb_domain_approve_switch(struct tb *tb, struct tb_switch *sw);
368int tb_domain_approve_switch_key(struct tb *tb, struct tb_switch *sw); 378int tb_domain_approve_switch_key(struct tb *tb, struct tb_switch *sw);
369int tb_domain_challenge_switch_key(struct tb *tb, struct tb_switch *sw); 379int tb_domain_challenge_switch_key(struct tb *tb, struct tb_switch *sw);
diff --git a/drivers/thunderbolt/tb_msgs.h b/drivers/thunderbolt/tb_msgs.h
index bc13f8d6b804..2487e162c885 100644
--- a/drivers/thunderbolt/tb_msgs.h
+++ b/drivers/thunderbolt/tb_msgs.h
@@ -286,6 +286,8 @@ struct icm_ar_pkg_driver_ready_response {
286 u16 info; 286 u16 info;
287}; 287};
288 288
289#define ICM_AR_FLAGS_RTD3 BIT(6)
290
289#define ICM_AR_INFO_SLEVEL_MASK GENMASK(3, 0) 291#define ICM_AR_INFO_SLEVEL_MASK GENMASK(3, 0)
290#define ICM_AR_INFO_BOOT_ACL_SHIFT 7 292#define ICM_AR_INFO_BOOT_ACL_SHIFT 7
291#define ICM_AR_INFO_BOOT_ACL_MASK GENMASK(11, 7) 293#define ICM_AR_INFO_BOOT_ACL_MASK GENMASK(11, 7)
@@ -333,6 +335,8 @@ struct icm_tr_pkg_driver_ready_response {
333 u16 reserved2; 335 u16 reserved2;
334}; 336};
335 337
338#define ICM_TR_FLAGS_RTD3 BIT(6)
339
336#define ICM_TR_INFO_SLEVEL_MASK GENMASK(2, 0) 340#define ICM_TR_INFO_SLEVEL_MASK GENMASK(2, 0)
337#define ICM_TR_INFO_BOOT_ACL_SHIFT 7 341#define ICM_TR_INFO_BOOT_ACL_SHIFT 7
338#define ICM_TR_INFO_BOOT_ACL_MASK GENMASK(12, 7) 342#define ICM_TR_INFO_BOOT_ACL_MASK GENMASK(12, 7)
diff --git a/drivers/thunderbolt/xdomain.c b/drivers/thunderbolt/xdomain.c
index 8abb4e843085..db8bece63327 100644
--- a/drivers/thunderbolt/xdomain.c
+++ b/drivers/thunderbolt/xdomain.c
@@ -13,6 +13,7 @@
13#include <linux/device.h> 13#include <linux/device.h>
14#include <linux/kmod.h> 14#include <linux/kmod.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/pm_runtime.h>
16#include <linux/utsname.h> 17#include <linux/utsname.h>
17#include <linux/uuid.h> 18#include <linux/uuid.h>
18#include <linux/workqueue.h> 19#include <linux/workqueue.h>
@@ -1129,6 +1130,14 @@ struct tb_xdomain *tb_xdomain_alloc(struct tb *tb, struct device *parent,
1129 xd->dev.groups = xdomain_attr_groups; 1130 xd->dev.groups = xdomain_attr_groups;
1130 dev_set_name(&xd->dev, "%u-%llx", tb->index, route); 1131 dev_set_name(&xd->dev, "%u-%llx", tb->index, route);
1131 1132
1133 /*
1134 * This keeps the DMA powered on as long as we have active
1135 * connection to another host.
1136 */
1137 pm_runtime_set_active(&xd->dev);
1138 pm_runtime_get_noresume(&xd->dev);
1139 pm_runtime_enable(&xd->dev);
1140
1132 return xd; 1141 return xd;
1133 1142
1134err_free_local_uuid: 1143err_free_local_uuid:
@@ -1174,6 +1183,15 @@ void tb_xdomain_remove(struct tb_xdomain *xd)
1174 1183
1175 device_for_each_child_reverse(&xd->dev, xd, unregister_service); 1184 device_for_each_child_reverse(&xd->dev, xd, unregister_service);
1176 1185
1186 /*
1187 * Undo runtime PM here explicitly because it is possible that
1188 * the XDomain was never added to the bus and thus device_del()
1189 * is not called for it (device_del() would handle this otherwise).
1190 */
1191 pm_runtime_disable(&xd->dev);
1192 pm_runtime_put_noidle(&xd->dev);
1193 pm_runtime_set_suspended(&xd->dev);
1194
1177 if (!device_is_registered(&xd->dev)) 1195 if (!device_is_registered(&xd->dev))
1178 put_device(&xd->dev); 1196 put_device(&xd->dev);
1179 else 1197 else