fwnode = fwnode_find_reference(acpi_fwnode_handle(adev), "usb4-host-interface", 0); if (IS_ERR(fwnode)) return AE_OK;
/* It needs to reference this NHI */ if (dev_fwnode(&nhi->pdev->dev) != fwnode) goto out_put;
/* * Ignore USB3 ports here as USB core will set up device links between * tunneled USB3 devices and NHI host during USB device creation. * USB3 ports might not even have a physical device yet if xHCI driver * isn't bound yet.
*/
dev = acpi_get_first_physical_node(adev); if (!dev || !dev_is_pci(dev)) goto out_put;
/* Check that this matches a PCIe root/downstream port. */
pdev = to_pci_dev(dev); if (pci_is_pcie(pdev) &&
(pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT ||
pci_pcie_type(pdev) == PCI_EXP_TYPE_DOWNSTREAM)) { conststruct device_link *link;
/* * Make them both active first to make sure the NHI does * not runtime suspend before the consumer. The * pm_runtime_put() below then allows the consumer to * runtime suspend again (which then allows NHI runtime * suspend too now that the device link is established).
*/
pm_runtime_get_sync(&pdev->dev);
link = device_link_add(&pdev->dev, &nhi->pdev->dev,
DL_FLAG_AUTOREMOVE_SUPPLIER |
DL_FLAG_RPM_ACTIVE |
DL_FLAG_PM_RUNTIME); if (link) {
dev_dbg(&nhi->pdev->dev, "created link from %s\n",
dev_name(&pdev->dev));
*(bool *)ret = true;
} else {
dev_warn(&nhi->pdev->dev, "device link creation from %s failed\n",
dev_name(&pdev->dev));
}
/** * tb_acpi_add_links() - Add device links based on ACPI description * @nhi: Pointer to NHI * * Goes over ACPI namespace finding tunneled ports that reference to * @nhi ACPI node. For each reference a device link is added. The link * is automatically removed by the driver core. * * Returns %true if at least one link was created.
*/ bool tb_acpi_add_links(struct tb_nhi *nhi)
{
acpi_status status; bool ret = false;
if (!has_acpi_companion(&nhi->pdev->dev)) returnfalse;
/* * Find all devices that have usb4-host-controller interface * property that references to this NHI.
*/
status = acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 32,
tb_acpi_add_link, NULL, nhi, (void **)&ret); if (ACPI_FAILURE(status)) {
dev_warn(&nhi->pdev->dev, "failed to enumerate tunneled ports\n"); returnfalse;
}
return ret;
}
/** * tb_acpi_is_native() - Did the platform grant native TBT/USB4 control * * Returns %true if the platform granted OS native control over * TBT/USB4. In this case software based connection manager can be used, * otherwise there is firmware based connection manager running.
*/ bool tb_acpi_is_native(void)
{ return osc_sb_native_usb4_support_confirmed &&
osc_sb_native_usb4_control;
}
/** * tb_acpi_may_tunnel_usb3() - Is USB3 tunneling allowed by the platform * * When software based connection manager is used, this function * returns %true if platform allows native USB3 tunneling.
*/ bool tb_acpi_may_tunnel_usb3(void)
{ if (tb_acpi_is_native()) return osc_sb_native_usb4_control & OSC_USB_USB3_TUNNELING; returntrue;
}
/** * tb_acpi_may_tunnel_dp() - Is DisplayPort tunneling allowed by the platform * * When software based connection manager is used, this function * returns %true if platform allows native DP tunneling.
*/ bool tb_acpi_may_tunnel_dp(void)
{ if (tb_acpi_is_native()) return osc_sb_native_usb4_control & OSC_USB_DP_TUNNELING; returntrue;
}
/** * tb_acpi_may_tunnel_pcie() - Is PCIe tunneling allowed by the platform * * When software based connection manager is used, this function * returns %true if platform allows native PCIe tunneling.
*/ bool tb_acpi_may_tunnel_pcie(void)
{ if (tb_acpi_is_native()) return osc_sb_native_usb4_control & OSC_USB_PCIE_TUNNELING; returntrue;
}
/** * tb_acpi_is_xdomain_allowed() - Are XDomain connections allowed * * When software based connection manager is used, this function * returns %true if platform allows XDomain connections.
*/ bool tb_acpi_is_xdomain_allowed(void)
{ if (tb_acpi_is_native()) return osc_sb_native_usb4_control & OSC_USB_XDOMAIN; returntrue;
}
obj = acpi_evaluate_dsm_typed(adev->handle, &retimer_dsm_guid, 1,
RETIMER_DSM_SET_ONLINE_STATE, argv4,
ACPI_TYPE_INTEGER); if (!obj) {
tb_port_warn(port, "ACPI: set online state _DSM evaluation failed\n"); return -EIO;
}
ret = obj->integer.value;
ACPI_FREE(obj);
if (ret >= 0) { if (power) return ret == 1 ? 0 : -EBUSY; return 0;
}
tb_port_warn(port, "ACPI: set online state _DSM failed with error %d\n", ret); return -EIO;
}
/** * tb_acpi_power_on_retimers() - Call platform to power on retimers * @port: USB4 port * * Calls platform to turn on power to all retimers behind this USB4 * port. After this function returns successfully the caller can * continue with the normal retimer flows (as specified in the USB4 * spec). Note if this returns %-EBUSY it means the type-C port is in * non-USB4/TBT mode (there is non-USB4/TBT device connected). * * This should only be called if the USB4/TBT link is not up. * * Returns %0 on success.
*/ int tb_acpi_power_on_retimers(struct tb_port *port)
{ return tb_acpi_retimer_set_power(port, true);
}
/** * tb_acpi_power_off_retimers() - Call platform to power off retimers * @port: USB4 port * * This is the opposite of tb_acpi_power_on_retimers(). After returning * successfully the normal operations with the @port can continue. * * Returns %0 on success.
*/ int tb_acpi_power_off_retimers(struct tb_port *port)
{ return tb_acpi_retimer_set_power(port, false);
}
/* * Device routers exists under the downstream facing USB4 port * of the parent router. Their _ADR is always 0.
*/ if (parent_sw) { struct tb_port *port = tb_switch_downstream_port(sw); struct acpi_device *port_adev;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.