summaryrefslogtreecommitdiffstats
path: root/drivers/thunderbolt
diff options
context:
space:
mode:
authorMika Westerberg <mika.westerberg@linux.intel.com>2017-06-06 08:25:01 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-06-09 05:42:42 -0400
commitbfe778ac49826ced3dceb6416038e1cd887ce2bd (patch)
tree194b78bdbef54c49b4b98109414925550db383d3 /drivers/thunderbolt
parent9d3cce0b613689ee849a505ffac179af0ae9fff2 (diff)
thunderbolt: Convert switch to a device
Thunderbolt domain consists of switches that are connected to each other, forming a bus. This will convert each switch into a real Linux device structure and adds them to the domain. The advantage here is that we get all the goodies from the driver core, like reference counting and sysfs hierarchy for free. Also expose device identification information to the userspace via new sysfs attributes. In order to support internal connection manager (ICM) we separate switch configuration into its own function (tb_switch_configure()) which is only called by the existing native connection manager implementation used on Macs. 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/eeprom.c2
-rw-r--r--drivers/thunderbolt/switch.c261
-rw-r--r--drivers/thunderbolt/tb.c40
-rw-r--r--drivers/thunderbolt/tb.h45
4 files changed, 281 insertions, 67 deletions
diff --git a/drivers/thunderbolt/eeprom.c b/drivers/thunderbolt/eeprom.c
index eb2179c98b09..7e485e3ef27e 100644
--- a/drivers/thunderbolt/eeprom.c
+++ b/drivers/thunderbolt/eeprom.c
@@ -479,6 +479,8 @@ parse:
479 goto err; 479 goto err;
480 } 480 }
481 sw->uid = header->uid; 481 sw->uid = header->uid;
482 sw->vendor = header->vendor_id;
483 sw->device = header->model_id;
482 484
483 crc = tb_crc32(sw->drom + TB_DROM_DATA_START, header->data_len); 485 crc = tb_crc32(sw->drom + TB_DROM_DATA_START, header->data_len);
484 if (crc != header->data_crc32) { 486 if (crc != header->data_crc32) {
diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c
index b379b4183bac..0475bfc6c208 100644
--- a/drivers/thunderbolt/switch.c
+++ b/drivers/thunderbolt/switch.c
@@ -281,6 +281,9 @@ static int tb_plug_events_active(struct tb_switch *sw, bool active)
281 u32 data; 281 u32 data;
282 int res; 282 int res;
283 283
284 if (!sw->config.enabled)
285 return 0;
286
284 sw->config.plug_events_delay = 0xff; 287 sw->config.plug_events_delay = 0xff;
285 res = tb_sw_write(sw, ((u32 *) &sw->config) + 4, TB_CFG_SWITCH, 4, 1); 288 res = tb_sw_write(sw, ((u32 *) &sw->config) + 4, TB_CFG_SWITCH, 4, 1);
286 if (res) 289 if (res)
@@ -307,36 +310,79 @@ static int tb_plug_events_active(struct tb_switch *sw, bool active)
307 sw->cap_plug_events + 1, 1); 310 sw->cap_plug_events + 1, 1);
308} 311}
309 312
313static ssize_t device_show(struct device *dev, struct device_attribute *attr,
314 char *buf)
315{
316 struct tb_switch *sw = tb_to_switch(dev);
310 317
311/** 318 return sprintf(buf, "%#x\n", sw->device);
312 * tb_switch_free() - free a tb_switch and all downstream switches 319}
313 */ 320static DEVICE_ATTR_RO(device);
314void tb_switch_free(struct tb_switch *sw) 321
322static ssize_t vendor_show(struct device *dev, struct device_attribute *attr,
323 char *buf)
315{ 324{
316 int i; 325 struct tb_switch *sw = tb_to_switch(dev);
317 /* port 0 is the switch itself and never has a remote */
318 for (i = 1; i <= sw->config.max_port_number; i++) {
319 if (tb_is_upstream_port(&sw->ports[i]))
320 continue;
321 if (sw->ports[i].remote)
322 tb_switch_free(sw->ports[i].remote->sw);
323 sw->ports[i].remote = NULL;
324 }
325 326
326 if (!sw->is_unplugged) 327 return sprintf(buf, "%#x\n", sw->vendor);
327 tb_plug_events_active(sw, false); 328}
329static DEVICE_ATTR_RO(vendor);
330
331static ssize_t unique_id_show(struct device *dev, struct device_attribute *attr,
332 char *buf)
333{
334 struct tb_switch *sw = tb_to_switch(dev);
335
336 return sprintf(buf, "%pUb\n", sw->uuid);
337}
338static DEVICE_ATTR_RO(unique_id);
339
340static struct attribute *switch_attrs[] = {
341 &dev_attr_device.attr,
342 &dev_attr_vendor.attr,
343 &dev_attr_unique_id.attr,
344 NULL,
345};
346
347static struct attribute_group switch_group = {
348 .attrs = switch_attrs,
349};
328 350
351static const struct attribute_group *switch_groups[] = {
352 &switch_group,
353 NULL,
354};
355
356static void tb_switch_release(struct device *dev)
357{
358 struct tb_switch *sw = tb_to_switch(dev);
359
360 kfree(sw->uuid);
329 kfree(sw->ports); 361 kfree(sw->ports);
330 kfree(sw->drom); 362 kfree(sw->drom);
331 kfree(sw); 363 kfree(sw);
332} 364}
333 365
366struct device_type tb_switch_type = {
367 .name = "thunderbolt_device",
368 .release = tb_switch_release,
369};
370
334/** 371/**
335 * tb_switch_alloc() - allocate and initialize a switch 372 * tb_switch_alloc() - allocate a switch
373 * @tb: Pointer to the owning domain
374 * @parent: Parent device for this switch
375 * @route: Route string for this switch
336 * 376 *
337 * Return: Returns a NULL on failure. 377 * Allocates and initializes a switch. Will not upload configuration to
378 * the switch. For that you need to call tb_switch_configure()
379 * separately. The returned switch should be released by calling
380 * tb_switch_put().
381 *
382 * Return: Pointer to the allocated switch or %NULL in case of failure
338 */ 383 */
339struct tb_switch *tb_switch_alloc(struct tb *tb, u64 route) 384struct tb_switch *tb_switch_alloc(struct tb *tb, struct device *parent,
385 u64 route)
340{ 386{
341 int i; 387 int i;
342 int cap; 388 int cap;
@@ -351,11 +397,9 @@ struct tb_switch *tb_switch_alloc(struct tb *tb, u64 route)
351 397
352 sw->tb = tb; 398 sw->tb = tb;
353 if (tb_cfg_read(tb->ctl, &sw->config, route, 0, TB_CFG_SWITCH, 0, 5)) 399 if (tb_cfg_read(tb->ctl, &sw->config, route, 0, TB_CFG_SWITCH, 0, 5))
354 goto err; 400 goto err_free_sw_ports;
355 tb_info(tb, 401
356 "initializing Switch at %#llx (depth: %d, up port: %d)\n", 402 tb_info(tb, "current switch config:\n");
357 route, tb_route_length(route), upstream_port);
358 tb_info(tb, "old switch config:\n");
359 tb_dump_switch(tb, &sw->config); 403 tb_dump_switch(tb, &sw->config);
360 404
361 /* configure switch */ 405 /* configure switch */
@@ -363,30 +407,13 @@ struct tb_switch *tb_switch_alloc(struct tb *tb, u64 route)
363 sw->config.depth = tb_route_length(route); 407 sw->config.depth = tb_route_length(route);
364 sw->config.route_lo = route; 408 sw->config.route_lo = route;
365 sw->config.route_hi = route >> 32; 409 sw->config.route_hi = route >> 32;
366 sw->config.enabled = 1; 410 sw->config.enabled = 0;
367 /* from here on we may use the tb_sw_* functions & macros */
368
369 if (sw->config.vendor_id != 0x8086)
370 tb_sw_warn(sw, "unknown switch vendor id %#x\n",
371 sw->config.vendor_id);
372
373 if (sw->config.device_id != PCI_DEVICE_ID_INTEL_LIGHT_RIDGE &&
374 sw->config.device_id != PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C &&
375 sw->config.device_id != PCI_DEVICE_ID_INTEL_PORT_RIDGE &&
376 sw->config.device_id != PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_BRIDGE &&
377 sw->config.device_id != PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_BRIDGE)
378 tb_sw_warn(sw, "unsupported switch device id %#x\n",
379 sw->config.device_id);
380
381 /* upload configuration */
382 if (tb_sw_write(sw, 1 + (u32 *) &sw->config, TB_CFG_SWITCH, 1, 3))
383 goto err;
384 411
385 /* initialize ports */ 412 /* initialize ports */
386 sw->ports = kcalloc(sw->config.max_port_number + 1, sizeof(*sw->ports), 413 sw->ports = kcalloc(sw->config.max_port_number + 1, sizeof(*sw->ports),
387 GFP_KERNEL); 414 GFP_KERNEL);
388 if (!sw->ports) 415 if (!sw->ports)
389 goto err; 416 goto err_free_sw_ports;
390 417
391 for (i = 0; i <= sw->config.max_port_number; i++) { 418 for (i = 0; i <= sw->config.max_port_number; i++) {
392 /* minimum setup for tb_find_cap and tb_drom_read to work */ 419 /* minimum setup for tb_find_cap and tb_drom_read to work */
@@ -397,35 +424,161 @@ struct tb_switch *tb_switch_alloc(struct tb *tb, u64 route)
397 cap = tb_switch_find_vse_cap(sw, TB_VSE_CAP_PLUG_EVENTS); 424 cap = tb_switch_find_vse_cap(sw, TB_VSE_CAP_PLUG_EVENTS);
398 if (cap < 0) { 425 if (cap < 0) {
399 tb_sw_warn(sw, "cannot find TB_VSE_CAP_PLUG_EVENTS aborting\n"); 426 tb_sw_warn(sw, "cannot find TB_VSE_CAP_PLUG_EVENTS aborting\n");
400 goto err; 427 goto err_free_sw_ports;
401 } 428 }
402 sw->cap_plug_events = cap; 429 sw->cap_plug_events = cap;
403 430
431 device_initialize(&sw->dev);
432 sw->dev.parent = parent;
433 sw->dev.bus = &tb_bus_type;
434 sw->dev.type = &tb_switch_type;
435 sw->dev.groups = switch_groups;
436 dev_set_name(&sw->dev, "%u-%llx", tb->index, tb_route(sw));
437
438 return sw;
439
440err_free_sw_ports:
441 kfree(sw->ports);
442 kfree(sw);
443
444 return NULL;
445}
446
447/**
448 * tb_switch_configure() - Uploads configuration to the switch
449 * @sw: Switch to configure
450 *
451 * Call this function before the switch is added to the system. It will
452 * upload configuration to the switch and makes it available for the
453 * connection manager to use.
454 *
455 * Return: %0 in case of success and negative errno in case of failure
456 */
457int tb_switch_configure(struct tb_switch *sw)
458{
459 struct tb *tb = sw->tb;
460 u64 route;
461 int ret;
462
463 route = tb_route(sw);
464 tb_info(tb,
465 "initializing Switch at %#llx (depth: %d, up port: %d)\n",
466 route, tb_route_length(route), sw->config.upstream_port_number);
467
468 if (sw->config.vendor_id != PCI_VENDOR_ID_INTEL)
469 tb_sw_warn(sw, "unknown switch vendor id %#x\n",
470 sw->config.vendor_id);
471
472 if (sw->config.device_id != PCI_DEVICE_ID_INTEL_LIGHT_RIDGE &&
473 sw->config.device_id != PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C &&
474 sw->config.device_id != PCI_DEVICE_ID_INTEL_PORT_RIDGE &&
475 sw->config.device_id != PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_BRIDGE &&
476 sw->config.device_id != PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_BRIDGE)
477 tb_sw_warn(sw, "unsupported switch device id %#x\n",
478 sw->config.device_id);
479
480 sw->config.enabled = 1;
481
482 /* upload configuration */
483 ret = tb_sw_write(sw, 1 + (u32 *)&sw->config, TB_CFG_SWITCH, 1, 3);
484 if (ret)
485 return ret;
486
487 return tb_plug_events_active(sw, true);
488}
489
490static void tb_switch_set_uuid(struct tb_switch *sw)
491{
492 u32 uuid[4];
493 int cap;
494
495 if (sw->uuid)
496 return;
497
498 /*
499 * The newer controllers include fused UUID as part of link
500 * controller specific registers
501 */
502 cap = tb_switch_find_vse_cap(sw, TB_VSE_CAP_LINK_CONTROLLER);
503 if (cap > 0) {
504 tb_sw_read(sw, uuid, TB_CFG_SWITCH, cap + 3, 4);
505 } else {
506 /*
507 * ICM generates UUID based on UID and fills the upper
508 * two words with ones. This is not strictly following
509 * UUID format but we want to be compatible with it so
510 * we do the same here.
511 */
512 uuid[0] = sw->uid & 0xffffffff;
513 uuid[1] = (sw->uid >> 32) & 0xffffffff;
514 uuid[2] = 0xffffffff;
515 uuid[3] = 0xffffffff;
516 }
517
518 sw->uuid = kmemdup(uuid, sizeof(uuid), GFP_KERNEL);
519}
520
521/**
522 * tb_switch_add() - Add a switch to the domain
523 * @sw: Switch to add
524 *
525 * This is the last step in adding switch to the domain. It will read
526 * identification information from DROM and initializes ports so that
527 * they can be used to connect other switches. The switch will be
528 * exposed to the userspace when this function successfully returns. To
529 * remove and release the switch, call tb_switch_remove().
530 *
531 * Return: %0 in case of success and negative errno in case of failure
532 */
533int tb_switch_add(struct tb_switch *sw)
534{
535 int i, ret;
536
404 /* read drom */ 537 /* read drom */
405 if (tb_drom_read(sw)) 538 if (tb_drom_read(sw))
406 tb_sw_warn(sw, "tb_eeprom_read_rom failed, continuing\n"); 539 tb_sw_warn(sw, "tb_eeprom_read_rom failed, continuing\n");
407 tb_sw_info(sw, "uid: %#llx\n", sw->uid); 540 tb_sw_info(sw, "uid: %#llx\n", sw->uid);
408 541
542 tb_switch_set_uuid(sw);
543
409 for (i = 0; i <= sw->config.max_port_number; i++) { 544 for (i = 0; i <= sw->config.max_port_number; i++) {
410 if (sw->ports[i].disabled) { 545 if (sw->ports[i].disabled) {
411 tb_port_info(&sw->ports[i], "disabled by eeprom\n"); 546 tb_port_info(&sw->ports[i], "disabled by eeprom\n");
412 continue; 547 continue;
413 } 548 }
414 if (tb_init_port(&sw->ports[i])) 549 ret = tb_init_port(&sw->ports[i]);
415 goto err; 550 if (ret)
551 return ret;
416 } 552 }
417 553
418 /* TODO: I2C, IECS, link controller */ 554 return device_add(&sw->dev);
555}
419 556
420 if (tb_plug_events_active(sw, true)) 557/**
421 goto err; 558 * tb_switch_remove() - Remove and release a switch
559 * @sw: Switch to remove
560 *
561 * This will remove the switch from the domain and release it after last
562 * reference count drops to zero. If there are switches connected below
563 * this switch, they will be removed as well.
564 */
565void tb_switch_remove(struct tb_switch *sw)
566{
567 int i;
422 568
423 return sw; 569 /* port 0 is the switch itself and never has a remote */
424err: 570 for (i = 1; i <= sw->config.max_port_number; i++) {
425 kfree(sw->ports); 571 if (tb_is_upstream_port(&sw->ports[i]))
426 kfree(sw->drom); 572 continue;
427 kfree(sw); 573 if (sw->ports[i].remote)
428 return NULL; 574 tb_switch_remove(sw->ports[i].remote->sw);
575 sw->ports[i].remote = NULL;
576 }
577
578 if (!sw->is_unplugged)
579 tb_plug_events_active(sw, false);
580
581 device_unregister(&sw->dev);
429} 582}
430 583
431/** 584/**
diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c
index 9f00a0f28d53..94ecac012428 100644
--- a/drivers/thunderbolt/tb.c
+++ b/drivers/thunderbolt/tb.c
@@ -61,9 +61,21 @@ static void tb_scan_port(struct tb_port *port)
61 tb_port_WARN(port, "port already has a remote!\n"); 61 tb_port_WARN(port, "port already has a remote!\n");
62 return; 62 return;
63 } 63 }
64 sw = tb_switch_alloc(port->sw->tb, tb_downstream_route(port)); 64 sw = tb_switch_alloc(port->sw->tb, &port->sw->dev,
65 tb_downstream_route(port));
65 if (!sw) 66 if (!sw)
66 return; 67 return;
68
69 if (tb_switch_configure(sw)) {
70 tb_switch_put(sw);
71 return;
72 }
73
74 if (tb_switch_add(sw)) {
75 tb_switch_put(sw);
76 return;
77 }
78
67 port->remote = tb_upstream_port(sw); 79 port->remote = tb_upstream_port(sw);
68 tb_upstream_port(sw)->remote = port; 80 tb_upstream_port(sw)->remote = port;
69 tb_scan_switch(sw); 81 tb_scan_switch(sw);
@@ -100,7 +112,7 @@ static void tb_free_unplugged_children(struct tb_switch *sw)
100 if (!port->remote) 112 if (!port->remote)
101 continue; 113 continue;
102 if (port->remote->sw->is_unplugged) { 114 if (port->remote->sw->is_unplugged) {
103 tb_switch_free(port->remote->sw); 115 tb_switch_remove(port->remote->sw);
104 port->remote = NULL; 116 port->remote = NULL;
105 } else { 117 } else {
106 tb_free_unplugged_children(port->remote->sw); 118 tb_free_unplugged_children(port->remote->sw);
@@ -266,7 +278,7 @@ static void tb_handle_hotplug(struct work_struct *work)
266 tb_port_info(port, "unplugged\n"); 278 tb_port_info(port, "unplugged\n");
267 tb_sw_set_unplugged(port->remote->sw); 279 tb_sw_set_unplugged(port->remote->sw);
268 tb_free_invalid_tunnels(tb); 280 tb_free_invalid_tunnels(tb);
269 tb_switch_free(port->remote->sw); 281 tb_switch_remove(port->remote->sw);
270 port->remote = NULL; 282 port->remote = NULL;
271 } else { 283 } else {
272 tb_port_info(port, 284 tb_port_info(port,
@@ -325,22 +337,32 @@ static void tb_stop(struct tb *tb)
325 tb_pci_deactivate(tunnel); 337 tb_pci_deactivate(tunnel);
326 tb_pci_free(tunnel); 338 tb_pci_free(tunnel);
327 } 339 }
328 340 tb_switch_remove(tb->root_switch);
329 if (tb->root_switch)
330 tb_switch_free(tb->root_switch);
331 tb->root_switch = NULL;
332
333 tcm->hotplug_active = false; /* signal tb_handle_hotplug to quit */ 341 tcm->hotplug_active = false; /* signal tb_handle_hotplug to quit */
334} 342}
335 343
336static int tb_start(struct tb *tb) 344static int tb_start(struct tb *tb)
337{ 345{
338 struct tb_cm *tcm = tb_priv(tb); 346 struct tb_cm *tcm = tb_priv(tb);
347 int ret;
339 348
340 tb->root_switch = tb_switch_alloc(tb, 0); 349 tb->root_switch = tb_switch_alloc(tb, &tb->dev, 0);
341 if (!tb->root_switch) 350 if (!tb->root_switch)
342 return -ENOMEM; 351 return -ENOMEM;
343 352
353 ret = tb_switch_configure(tb->root_switch);
354 if (ret) {
355 tb_switch_put(tb->root_switch);
356 return ret;
357 }
358
359 /* Announce the switch to the world */
360 ret = tb_switch_add(tb->root_switch);
361 if (ret) {
362 tb_switch_put(tb->root_switch);
363 return ret;
364 }
365
344 /* Full scan to discover devices added before the driver was loaded. */ 366 /* Full scan to discover devices added before the driver was loaded. */
345 tb_scan_switch(tb->root_switch); 367 tb_scan_switch(tb->root_switch);
346 tb_activate_pcie_devices(tb); 368 tb_activate_pcie_devices(tb);
diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h
index 5fab4c44f124..f7dfe733d71a 100644
--- a/drivers/thunderbolt/tb.h
+++ b/drivers/thunderbolt/tb.h
@@ -8,20 +8,36 @@
8#define TB_H_ 8#define TB_H_
9 9
10#include <linux/pci.h> 10#include <linux/pci.h>
11#include <linux/uuid.h>
11 12
12#include "tb_regs.h" 13#include "tb_regs.h"
13#include "ctl.h" 14#include "ctl.h"
14 15
15/** 16/**
16 * struct tb_switch - a thunderbolt switch 17 * struct tb_switch - a thunderbolt switch
18 * @dev: Device for the switch
19 * @config: Switch configuration
20 * @ports: Ports in this switch
21 * @tb: Pointer to the domain the switch belongs to
22 * @uid: Unique ID of the switch
23 * @uuid: UUID of the switch (or %NULL if not supported)
24 * @vendor: Vendor ID of the switch
25 * @device: Device ID of the switch
26 * @cap_plug_events: Offset to the plug events capability (%0 if not found)
27 * @is_unplugged: The switch is going away
28 * @drom: DROM of the switch (%NULL if not found)
17 */ 29 */
18struct tb_switch { 30struct tb_switch {
31 struct device dev;
19 struct tb_regs_switch_header config; 32 struct tb_regs_switch_header config;
20 struct tb_port *ports; 33 struct tb_port *ports;
21 struct tb *tb; 34 struct tb *tb;
22 u64 uid; 35 u64 uid;
23 int cap_plug_events; /* offset, zero if not found */ 36 uuid_be *uuid;
24 bool is_unplugged; /* unplugged, will go away */ 37 u16 vendor;
38 u16 device;
39 int cap_plug_events;
40 bool is_unplugged;
25 u8 *drom; 41 u8 *drom;
26}; 42};
27 43
@@ -242,6 +258,7 @@ struct tb *tb_probe(struct tb_nhi *nhi);
242 258
243extern struct bus_type tb_bus_type; 259extern struct bus_type tb_bus_type;
244extern struct device_type tb_domain_type; 260extern struct device_type tb_domain_type;
261extern struct device_type tb_switch_type;
245 262
246int tb_domain_init(void); 263int tb_domain_init(void);
247void tb_domain_exit(void); 264void tb_domain_exit(void);
@@ -257,14 +274,34 @@ static inline void tb_domain_put(struct tb *tb)
257 put_device(&tb->dev); 274 put_device(&tb->dev);
258} 275}
259 276
260struct tb_switch *tb_switch_alloc(struct tb *tb, u64 route); 277struct tb_switch *tb_switch_alloc(struct tb *tb, struct device *parent,
261void tb_switch_free(struct tb_switch *sw); 278 u64 route);
279int tb_switch_configure(struct tb_switch *sw);
280int tb_switch_add(struct tb_switch *sw);
281void tb_switch_remove(struct tb_switch *sw);
262void tb_switch_suspend(struct tb_switch *sw); 282void tb_switch_suspend(struct tb_switch *sw);
263int tb_switch_resume(struct tb_switch *sw); 283int tb_switch_resume(struct tb_switch *sw);
264int tb_switch_reset(struct tb *tb, u64 route); 284int tb_switch_reset(struct tb *tb, u64 route);
265void tb_sw_set_unplugged(struct tb_switch *sw); 285void tb_sw_set_unplugged(struct tb_switch *sw);
266struct tb_switch *get_switch_at_route(struct tb_switch *sw, u64 route); 286struct tb_switch *get_switch_at_route(struct tb_switch *sw, u64 route);
267 287
288static inline void tb_switch_put(struct tb_switch *sw)
289{
290 put_device(&sw->dev);
291}
292
293static inline bool tb_is_switch(const struct device *dev)
294{
295 return dev->type == &tb_switch_type;
296}
297
298static inline struct tb_switch *tb_to_switch(struct device *dev)
299{
300 if (tb_is_switch(dev))
301 return container_of(dev, struct tb_switch, dev);
302 return NULL;
303}
304
268int tb_wait_for_port(struct tb_port *port, bool wait_if_unplugged); 305int tb_wait_for_port(struct tb_port *port, bool wait_if_unplugged);
269int tb_port_add_nfc_credits(struct tb_port *port, int credits); 306int tb_port_add_nfc_credits(struct tb_port *port, int credits);
270int tb_port_clear_counter(struct tb_port *port, int counter); 307int tb_port_clear_counter(struct tb_port *port, int counter);