Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

thunderbolt: Runtime resume USB4 port when retimers are scanned

Sometimes when plugging in a USB4 device we might see following error:

thunderbolt 1-0:3.1: runtime PM trying to activate child device 1-0:3.1 but parent (usb4_port3) is not active

This happens because the parent USB4 port was still runtime suspended.
Fix this by runtime resuming the USB4 port before scanning the retimers
below it.

Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>

+18 -10
+18 -10
drivers/thunderbolt/retimer.c
··· 324 324 325 325 static int tb_retimer_add(struct tb_port *port, u8 index, u32 auth_status) 326 326 { 327 - struct usb4_port *usb4; 328 327 struct tb_retimer *rt; 329 328 u32 vendor, device; 330 329 int ret; 331 - 332 - usb4 = port->usb4; 333 - if (!usb4) 334 - return -EINVAL; 335 330 336 331 ret = usb4_port_retimer_read(port, index, USB4_SB_VENDOR_ID, &vendor, 337 332 sizeof(vendor)); ··· 369 374 rt->port = port; 370 375 rt->tb = port->sw->tb; 371 376 372 - rt->dev.parent = &usb4->dev; 377 + rt->dev.parent = &port->usb4->dev; 373 378 rt->dev.bus = &tb_bus_type; 374 379 rt->dev.type = &tb_retimer_type; 375 380 dev_set_name(&rt->dev, "%s:%u.%u", dev_name(&port->sw->dev), ··· 448 453 { 449 454 u32 status[TB_MAX_RETIMER_INDEX + 1] = {}; 450 455 int ret, i, last_idx = 0; 456 + struct usb4_port *usb4; 457 + 458 + usb4 = port->usb4; 459 + if (!usb4) 460 + return 0; 461 + 462 + pm_runtime_get_sync(&usb4->dev); 451 463 452 464 /* 453 465 * Send broadcast RT to make sure retimer indices facing this ··· 462 460 */ 463 461 ret = usb4_port_enumerate_retimers(port); 464 462 if (ret) 465 - return ret; 463 + goto out; 466 464 467 465 /* 468 466 * Enable sideband channel for each retimer. We can do this ··· 492 490 break; 493 491 } 494 492 495 - if (!last_idx) 496 - return 0; 493 + if (!last_idx) { 494 + ret = 0; 495 + goto out; 496 + } 497 497 498 498 /* Add on-board retimers if they do not exist already */ 499 499 for (i = 1; i <= last_idx; i++) { ··· 511 507 } 512 508 } 513 509 514 - return 0; 510 + out: 511 + pm_runtime_mark_last_busy(&usb4->dev); 512 + pm_runtime_put_autosuspend(&usb4->dev); 513 + 514 + return ret; 515 515 } 516 516 517 517 static int remove_retimer(struct device *dev, void *data)