Commit 4051a1c9 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman
Browse files

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

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

Mika writes:

thunderbolt: Changes for v6.2 merge window

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

  - Add wake on connect/disconnect for USB4 ports
  - A couple of minor cleanups

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

* tag 'thunderbolt-for-v6.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/westeri/thunderbolt:
  thunderbolt: Add wake on connect/disconnect on USB4 ports
  thunderbolt: ACPI: Use the helper fwnode_find_reference()
  thunderbolt: Remove redundant assignment to variable len
  thunderbolt: Use str_enabled_disabled() helper
parents b47ec972 a5cfc9d6
Loading
Loading
Loading
Loading
+4 −8
Original line number Diff line number Diff line
@@ -15,24 +15,20 @@ static acpi_status tb_acpi_add_link(acpi_handle handle, u32 level, void *data,
				    void **return_value)
{
	struct acpi_device *adev = acpi_fetch_acpi_dev(handle);
	struct fwnode_reference_args args;
	struct fwnode_handle *fwnode;
	struct tb_nhi *nhi = data;
	struct pci_dev *pdev;
	struct device *dev;
	int ret;

	if (!adev)
		return AE_OK;

	fwnode = acpi_fwnode_handle(adev);
	ret = fwnode_property_get_reference_args(fwnode, "usb4-host-interface",
						 NULL, 0, 0, &args);
	if (ret)
	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) != args.fwnode)
	if (dev_fwnode(&nhi->pdev->dev) != fwnode)
		goto out_put;

	/*
@@ -100,7 +96,7 @@ static acpi_status tb_acpi_add_link(acpi_handle handle, u32 level, void *data,
	}

out_put:
	fwnode_handle_put(args.fwnode);
	fwnode_handle_put(fwnode);
	return AE_OK;
}

+3 −2
Original line number Diff line number Diff line
@@ -8,12 +8,13 @@

#include <linux/delay.h>
#include <linux/idr.h>
#include <linux/module.h>
#include <linux/nvmem-provider.h>
#include <linux/pm_runtime.h>
#include <linux/sched/signal.h>
#include <linux/sizes.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/string_helpers.h>

#include "tb.h"

@@ -644,7 +645,7 @@ static int __tb_port_enable(struct tb_port *port, bool enable)
	if (ret)
		return ret;

	tb_port_dbg(port, "lane %sabled\n", enable ? "en" : "dis");
	tb_port_dbg(port, "lane %s\n", str_enabled_disabled(enable));
	return 0;
}

+2 −0
Original line number Diff line number Diff line
@@ -361,6 +361,8 @@ struct tb_regs_port_header {
#define PORT_CS_18_BE				BIT(8)
#define PORT_CS_18_TCM				BIT(9)
#define PORT_CS_18_CPS				BIT(10)
#define PORT_CS_18_WOCS				BIT(16)
#define PORT_CS_18_WODS				BIT(17)
#define PORT_CS_18_WOU4S			BIT(18)
#define PORT_CS_19				0x13
#define PORT_CS_19_PC				BIT(3)
+25 −8
Original line number Diff line number Diff line
@@ -155,6 +155,8 @@ static inline int usb4_switch_op_data(struct tb_switch *sw, u16 opcode,

static void usb4_switch_check_wakes(struct tb_switch *sw)
{
	bool wakeup_usb4 = false;
	struct usb4_port *usb4;
	struct tb_port *port;
	bool wakeup = false;
	u32 val;
@@ -173,20 +175,31 @@ static void usb4_switch_check_wakes(struct tb_switch *sw)
		wakeup = val & (ROUTER_CS_6_WOPS | ROUTER_CS_6_WOUS);
	}

	/* Check for any connected downstream ports for USB4 wake */
	/*
	 * Check for any downstream ports for USB4 wake,
	 * connection wake and disconnection wake.
	 */
	tb_switch_for_each_port(sw, port) {
		if (!tb_port_has_remote(port))
		if (!port->cap_usb4)
			continue;

		if (tb_port_read(port, &val, TB_CFG_PORT,
				 port->cap_usb4 + PORT_CS_18, 1))
			break;

		tb_port_dbg(port, "USB4 wake: %s\n",
			    (val & PORT_CS_18_WOU4S) ? "yes" : "no");
		tb_port_dbg(port, "USB4 wake: %s, connection wake: %s, disconnection wake: %s\n",
			    (val & PORT_CS_18_WOU4S) ? "yes" : "no",
			    (val & PORT_CS_18_WOCS) ? "yes" : "no",
			    (val & PORT_CS_18_WODS) ? "yes" : "no");

		if (val & PORT_CS_18_WOU4S)
			wakeup = true;
		wakeup_usb4 = val & (PORT_CS_18_WOU4S | PORT_CS_18_WOCS |
				     PORT_CS_18_WODS);

		usb4 = port->usb4;
		if (device_may_wakeup(&usb4->dev) && wakeup_usb4)
			pm_wakeup_event(&usb4->dev, 0);

		wakeup |= wakeup_usb4;
	}

	if (wakeup)
@@ -366,6 +379,7 @@ bool usb4_switch_lane_bonding_possible(struct tb_switch *sw)
 */
int usb4_switch_set_wake(struct tb_switch *sw, unsigned int flags)
{
	struct usb4_port *usb4;
	struct tb_port *port;
	u64 route = tb_route(sw);
	u32 val;
@@ -395,10 +409,13 @@ int usb4_switch_set_wake(struct tb_switch *sw, unsigned int flags)
			val |= PORT_CS_19_WOU4;
		} else {
			bool configured = val & PORT_CS_19_PC;
			usb4 = port->usb4;

			if ((flags & TB_WAKE_ON_CONNECT) && !configured)
			if (((flags & TB_WAKE_ON_CONNECT) |
			      device_may_wakeup(&usb4->dev)) && !configured)
				val |= PORT_CS_19_WOC;
			if ((flags & TB_WAKE_ON_DISCONNECT) && configured)
			if (((flags & TB_WAKE_ON_DISCONNECT) |
			      device_may_wakeup(&usb4->dev)) && configured)
				val |= PORT_CS_19_WOD;
			if ((flags & TB_WAKE_ON_USB4) && configured)
				val |= PORT_CS_19_WOU4;
+3 −0
Original line number Diff line number Diff line
@@ -284,6 +284,9 @@ struct usb4_port *usb4_port_device_add(struct tb_port *port)
		}
	}

	if (!tb_is_upstream_port(port))
		device_set_wakeup_capable(&usb4->dev, true);

	pm_runtime_no_callbacks(&usb4->dev);
	pm_runtime_set_active(&usb4->dev);
	pm_runtime_enable(&usb4->dev);
Loading