Commit 88e054e8 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman
Browse files

Merge tag 'thunderbolt-for-v6.3-rc1' of...

Merge tag 'thunderbolt-for-v6.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt into usb-next

Mika writes:

thunderbolt: Changes for v6.3 merge window

This includes following Thunderbolt/USB4 changes for the v6.3 merge
window:

  - Add support for DisplayPort bandwidth allocation mode
  - Debug logging improvements
  - Minor cleanups.

All these have been in linux-next with no reported issues.

* tag 'thunderbolt-for-v6.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt:
  thunderbolt: Add missing kernel-doc comment to tb_tunnel_maximum_bandwidth()
  thunderbolt: Handle bandwidth allocation mode enablement notification
  thunderbolt: Add support for DisplayPort bandwidth allocation mode
  thunderbolt: Include the additional DP IN double word in debugfs dump
  thunderbolt: Add functions to support DisplayPort bandwidth allocation mode
  thunderbolt: Increase timeout of DP OUT adapter handshake
  thunderbolt: Take CL states into account when waiting for link to come up
  thunderbolt: Improve debug logging in tb_available_bandwidth()
  thunderbolt: Log DP adapter type
  thunderbolt: Use decimal port number in control and tunnel logs too
  thunderbolt: Refactor tb_acpi_add_link()
  thunderbolt: Use correct type in tb_port_is_clx_enabled() prototype
parents cf13d6e4 06cbcbfa
Loading
Loading
Loading
Loading
+5 −8
Original line number Diff line number Diff line
@@ -36,16 +36,13 @@ static acpi_status tb_acpi_add_link(acpi_handle handle, u32 level, void *data,
	 * We need to do this because the xHCI driver might not yet be
	 * bound so the USB3 SuperSpeed ports are not yet created.
	 */
	do {
		dev = acpi_get_first_physical_node(adev);
	while (!dev) {
		adev = acpi_dev_parent(adev);
		if (!adev)
		if (dev)
			break;
		dev = acpi_get_first_physical_node(adev);
	}

	if (!dev)
		goto out_put;
		adev = acpi_dev_parent(adev);
	} while (adev);

	/*
	 * Check that the device is PCIe. This is because USB3
+43 −9
Original line number Diff line number Diff line
@@ -230,7 +230,6 @@ static int check_config_address(struct tb_cfg_address addr,
static struct tb_cfg_result decode_error(const struct ctl_pkg *response)
{
	struct cfg_error_pkg *pkg = response->buffer;
	struct tb_ctl *ctl = response->ctl;
	struct tb_cfg_result res = { 0 };
	res.response_route = tb_cfg_get_route(&pkg->header);
	res.response_port = 0;
@@ -239,13 +238,6 @@ static struct tb_cfg_result decode_error(const struct ctl_pkg *response)
	if (res.err)
		return res;

	if (pkg->zero1)
		tb_ctl_warn(ctl, "pkg->zero1 is %#x\n", pkg->zero1);
	if (pkg->zero2)
		tb_ctl_warn(ctl, "pkg->zero2 is %#x\n", pkg->zero2);
	if (pkg->zero3)
		tb_ctl_warn(ctl, "pkg->zero3 is %#x\n", pkg->zero3);

	res.err = 1;
	res.tb_error = pkg->error;
	res.response_port = pkg->port;
@@ -416,6 +408,7 @@ static int tb_async_error(const struct ctl_pkg *pkg)
	case TB_CFG_ERROR_LINK_ERROR:
	case TB_CFG_ERROR_HEC_ERROR_DETECTED:
	case TB_CFG_ERROR_FLOW_CONTROL_ERROR:
	case TB_CFG_ERROR_DP_BW:
		return true;

	default:
@@ -735,6 +728,47 @@ void tb_ctl_stop(struct tb_ctl *ctl)

/* public interface, commands */

/**
 * tb_cfg_ack_notification() - Ack notification
 * @ctl: Control channel to use
 * @route: Router that originated the event
 * @error: Pointer to the notification package
 *
 * Call this as response for non-plug notification to ack it. Returns
 * %0 on success or an error code on failure.
 */
int tb_cfg_ack_notification(struct tb_ctl *ctl, u64 route,
			    const struct cfg_error_pkg *error)
{
	struct cfg_ack_pkg pkg = {
		.header = tb_cfg_make_header(route),
	};
	const char *name;

	switch (error->error) {
	case TB_CFG_ERROR_LINK_ERROR:
		name = "link error";
		break;
	case TB_CFG_ERROR_HEC_ERROR_DETECTED:
		name = "HEC error";
		break;
	case TB_CFG_ERROR_FLOW_CONTROL_ERROR:
		name = "flow control error";
		break;
	case TB_CFG_ERROR_DP_BW:
		name = "DP_BW";
		break;
	default:
		name = "unknown";
		break;
	}

	tb_ctl_dbg(ctl, "acking %s (%#x) notification on %llx\n", name,
		   error->error, route);

	return tb_ctl_tx(ctl, &pkg, sizeof(pkg), TB_CFG_PKG_NOTIFY_ACK);
}

/**
 * tb_cfg_ack_plug() - Ack hot plug/unplug event
 * @ctl: Control channel to use
@@ -754,7 +788,7 @@ int tb_cfg_ack_plug(struct tb_ctl *ctl, u64 route, u32 port, bool unplug)
		.pg = unplug ? TB_CFG_ERROR_PG_HOT_UNPLUG
			     : TB_CFG_ERROR_PG_HOT_PLUG,
	};
	tb_ctl_dbg(ctl, "acking hot %splug event on %llx:%x\n",
	tb_ctl_dbg(ctl, "acking hot %splug event on %llx:%u\n",
		   unplug ? "un" : "", route, port);
	return tb_ctl_tx(ctl, &pkg, sizeof(pkg), TB_CFG_PKG_ERROR);
}
+2 −0
Original line number Diff line number Diff line
@@ -122,6 +122,8 @@ static inline struct tb_cfg_header tb_cfg_make_header(u64 route)
	return header;
}

int tb_cfg_ack_notification(struct tb_ctl *ctl, u64 route,
			    const struct cfg_error_pkg *error);
int tb_cfg_ack_plug(struct tb_ctl *ctl, u64 route, u32 port, bool unplug);
struct tb_cfg_result tb_cfg_reset(struct tb_ctl *ctl, u64 route);
struct tb_cfg_result tb_cfg_read_raw(struct tb_ctl *ctl, void *buffer,
+4 −1
Original line number Diff line number Diff line
@@ -1159,6 +1159,9 @@ static void port_cap_show(struct tb_port *port, struct seq_file *s,
		if (tb_port_is_pcie_down(port) || tb_port_is_pcie_up(port)) {
			length = PORT_CAP_PCIE_LEN;
		} else if (tb_port_is_dpin(port) || tb_port_is_dpout(port)) {
			if (usb4_dp_port_bw_mode_supported(port))
				length = PORT_CAP_DP_LEN + 1;
			else
				length = PORT_CAP_DP_LEN;
		} else if (tb_port_is_usb3_down(port) ||
			   tb_port_is_usb3_up(port)) {
+25 −17
Original line number Diff line number Diff line
@@ -513,27 +513,33 @@ int tb_wait_for_port(struct tb_port *port, bool wait_if_unplugged)

	while (retries--) {
		state = tb_port_state(port);
		if (state < 0)
			return state;
		if (state == TB_PORT_DISABLED) {
		switch (state) {
		case TB_PORT_DISABLED:
			tb_port_dbg(port, "is disabled (state: 0)\n");
			return 0;
		}
		if (state == TB_PORT_UNPLUGGED) {

		case TB_PORT_UNPLUGGED:
			if (wait_if_unplugged) {
				/* used during resume */
				tb_port_dbg(port,
					    "is unplugged (state: 7), retrying...\n");
				msleep(100);
				continue;
				break;
			}
			tb_port_dbg(port, "is unplugged (state: 7)\n");
			return 0;
		}
		if (state == TB_PORT_UP) {
			tb_port_dbg(port, "is connected, link is up (state: 2)\n");

		case TB_PORT_UP:
		case TB_PORT_TX_CL0S:
		case TB_PORT_RX_CL0S:
		case TB_PORT_CL1:
		case TB_PORT_CL2:
			tb_port_dbg(port, "is connected, link is up (state: %d)\n", state);
			return 1;
		}

		default:
			if (state < 0)
				return state;

			/*
			 * After plug-in the state is TB_PORT_CONNECTING. Give it some
@@ -544,6 +550,8 @@ int tb_wait_for_port(struct tb_port *port, bool wait_if_unplugged)
				    state);
			msleep(100);
		}

	}
	tb_port_warn(port,
		     "failed to reach state TB_PORT_UP. Ignoring port...\n");
	return 0;
Loading