drivers/thunderbolt/usb4_port.c

Source file repositories/reference/linux-study-clean/drivers/thunderbolt/usb4_port.c

File Facts

System
Linux kernel
Corpus path
drivers/thunderbolt/usb4_port.c
Extension
.c
Size
8485 bytes
Lines
367
Domain
Driver Families
Bucket
drivers/thunderbolt
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0
/*
 * USB4 port device
 *
 * Copyright (C) 2021, Intel Corporation
 * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
 */

#include <linux/pm_runtime.h>
#include <linux/component.h>
#include <linux/property.h>

#include "tb.h"

static int connector_bind(struct device *dev, struct device *connector, void *data)
{
	int ret;

	ret = sysfs_create_link(&dev->kobj, &connector->kobj, "connector");
	if (ret)
		return ret;

	ret = sysfs_create_link(&connector->kobj, &dev->kobj, dev_name(dev));
	if (ret)
		sysfs_remove_link(&dev->kobj, "connector");

	return ret;
}

static void connector_unbind(struct device *dev, struct device *connector, void *data)
{
	sysfs_remove_link(&connector->kobj, dev_name(dev));
	sysfs_remove_link(&dev->kobj, "connector");
}

static const struct component_ops connector_ops = {
	.bind = connector_bind,
	.unbind = connector_unbind,
};

static ssize_t link_show(struct device *dev, struct device_attribute *attr,
			 char *buf)
{
	struct usb4_port *usb4 = tb_to_usb4_port_device(dev);
	struct tb_port *port = usb4->port;
	struct tb *tb = port->sw->tb;
	const char *link;

	if (mutex_lock_interruptible(&tb->lock))
		return -ERESTARTSYS;

	if (tb_is_upstream_port(port))
		link = port->sw->link_usb4 ? "usb4" : "tbt";
	else if (tb_port_has_remote(port))
		link = port->remote->sw->link_usb4 ? "usb4" : "tbt";
	else if (port->xdomain)
		link = port->xdomain->link_usb4 ? "usb4" : "tbt";
	else
		link = "none";

	mutex_unlock(&tb->lock);

	return sysfs_emit(buf, "%s\n", link);
}
static DEVICE_ATTR_RO(link);

static struct attribute *common_attrs[] = {
	&dev_attr_link.attr,
	NULL
};

static const struct attribute_group common_group = {
	.attrs = common_attrs,
};

static int usb4_port_offline(struct usb4_port *usb4)
{
	struct tb_port *port = usb4->port;
	int ret;

	ret = tb_acpi_power_on_retimers(port);
	if (ret)
		return ret;

	ret = usb4_port_router_offline(port);
	if (ret) {
		tb_acpi_power_off_retimers(port);
		return ret;
	}

Annotation

Implementation Notes